最近朋友推荐了这本书:FunctionalPHP。关于程序设计的很多思想都值得思考和借鉴。函数式编程不是框架或工具,而是一种编写代码的方式。FP是一种主要强调函数使用的软件开发风格。个人认为对重构代码很有帮助。例如,本书还谈到了PHP5.3中引入的闭包函数和高阶函数。在实际开发过程中,善于学习并灵活运用它们也是函数式风格的灵魂所在。解释的较新版本的PHP添加了严格的类型和标量类型声明。类型声明允许您使用适当的类或标量类型(布尔值、整数、字符串、MyClass等)来限定任何函数参数。这些在PHP5中作为“类型提示”得到部分支持,但没有标量支持。在PHP7中,您还可以声明函数返回值的类型。作为一种动态语言,PHP总是会尝试将错误类型的值强制转换为预期的标量类型。例如,当给定一个字符串时,期望整数参数的函数会将值强制转换为整数,文件顶部引用强制类型检测模式declare(strict_types=1);参数异常将抛出以下错误ePHPWarning:UncaughtTypeError:Argument1passedtoincrement()mustbeofthetypeinteger,stringgiven...声明式编码在翻译后感觉很模糊。看例子可能会更清楚更透彻。“函数式编程首先是一种声明式编程范式。这意味着它们表达了操作的逻辑联系,而没有揭示它们是如何实现的,或者数据实际上是如何流经它们的。它着重于使用表达式来描述程序的逻辑是什么“在PHP中,声明性代码是使用高阶函数实现的。我个人认为作者的意思是灵活使用系统自带的函数来处理逻辑,放弃复杂但不简洁的逻辑控制。代码越复杂,重构就越容易。越麻烦,bug率越高。一个简单的例子一个一个去。//方法1$array=[0,1,2,3,4,5,6,7,8,9];for($i=0;$i[0,1,4,9,16,25,36,49,64,81]//方法2$square=function(int$num):int{returnpow($num,2);};print_r(array_map($square,$array))//q:结果累加函数add(float$a,float$b):float{return$a+$b;}print_r(array_reduce(array_map($square,$数组),'添加'));//->285设计成不可变无状态的例子就是上面例子中使用的array_map的优点是不可变的,也就是说原数组的内容不会改变。使用不可变变量进行编码的优点如下:程序异常的主要原因之一是对象的状态无意中改变,或者其引用变为空。不可变对象可以传递给任何函数,它们的状态将始终保持不变。不可变数据结构在共享内存多线程应用程序中非常重要。在本书中,我们不会过多讨论并发性,因为PHP进程大多是孤立运行的。无状态对象现在是许多常见PHP部署中广泛使用的模式,无论是否为并行设计。例如,作为最佳实践,Symfony服务(或服务对象)应该始终是无状态的。服务不应该保留任何状态并提供一组临时函数来处理它所在的域、执行某种业务逻辑计算并返回结果。PHP对不可变变量的支持较差,在实际开发过程中使用defineconst关键字定义常量。对于define和const的比较。const是在编译时定义的,这意味着编译器可以巧妙地存储它们,但你不能有条件地声明它们。用define声明的常量是通用的和动态的。因为编译器在实际看到它们之前不会尝试为它们分配空间。defined($name)在使用常量($name)的值之前,您应该始终检查它是否已定义。例如//error:throwexceptionif(){constC1='FOO';}else{constC2='BAR';}//oknormalif(){define('C1','FOO')}else{define('C2','BAR')}纯函数函数式编程的前提是您基于纯函数构建不可变程序作为业务逻辑的构建块。高阶PHP正如本书关于高阶函数和闭包所提到的,高阶函数被定义为可以接受其他函数作为参数或返回其他函数的函数。当然函数可以赋值给变量。PHP中的函数可以像对象一样被操作。事实上,如果你要检查一个函数的类型,你会发现它们是Closure的实例。将函数赋值给变量在实际应用中很常见。例如,下面的例子$str=function(string$str1,string$str2){return$str1。''。$str2;}$str('你好','word');//outputhelloword;is_callable($str)//1此代码使用匿名函数(RHS)并将其分配给变量$str(LHS)。或者,您可以使用is_callable()来检查函数变量functions是否也可以从其他函数返回。这是创建函数族的非常有用的技术。functionconcatWith(string$a):callable{returnfunction(string$b)use($a):string{return$a.$b;};}$helloWith=concatWith('Hello');$helloWith('世界');//output->'HelloWorld'提供函数作为参数,创建一个简单的函数,该函数接受一个可调用函数并将其应用于其他参数functionapply(callable$operator,$a,$b){return$operator($a,$b);}$add=function(float$a,float$b):float{return$a+$b;};apply($add,1,2);//输出->3//或powerfunctionapply(callable$operator):callable{returnfunction($a,$b)use($operator){return$operator($a,$b);};}应用($添加)(5、5);//输出->10$adder=apply($add);$adder(5,5)//output->10遇到另一种情况,即两个数的相除分母不能为0,这时候最好建个空校验函数。始终检查变量的值是一个好习惯。functionsafeDivide(float$a,float$b):float{returnempty($b)?南:$a/$b;}apply($safeDivide)(5,0);//->NAN$result=apply($safeDivide)(5,0);if(!is_nan($result)){return$result;}else{Log::warning('出现数学错误!被零除!');}"这个方法避免了为了抛出异常。回想一下抛出异常的情况,会导致程序栈展开记录写入,但同样不尊重代码的局部性原则。在特别是,它不服从空间区域性,这表明相关的语句应该彼此靠近。这在CPU架构上有更多的应用,但也可以应用于代码设计。以后会明白这种翻译语句,说不定哪天会豁然开朗,毕竟这是一条很长的路。PHP还通过可调用对象将其提升到了一个新的水平。现在,这并不是一个真正的功能性概念,但如果使用得当,它可以成为一种非常强大的技术。事实上,在幕后,PHP的匿名函数语法被编译成一个类,并且有一个invoke()方法。检查数据的解释是通过调用函数类Demo{private$collect;来调用对象时的响应方法。公共函数__construct($num){$this->collect=$num;}publicfunctionincrement():int{return++$this->collect;}publicfunction__invoke(){return$this->increment();}}$demo=newDemo(1);echo$demo();//输出->2使用容器改进API使用包装器来控制对特定变量的访问并提供额外的行为。先看例子中的类,下面的例子扩展性更强classContainer{private$_value;私有函数__construct($value){$this->_value=$value;}//单元函数publicstaticfunctionof($val){returnnewstatic($val);}//映射函数publicfunctionmap(callable$f){returnstatic::of(call_user_func($f,$this->_value));}//打印出容器publicfunction__toString():string{return"Container[{$this->_value}]";}//引用容器publicfunction__invoke(){return$this->_value;}}functioncontainer_map(callable$f,Container$c):Container{return$c->map($f);}$c=Container::of('')->map('htmlspecialchars')->map('strtolower');$c;//output->Container[]Closure在PHP5.4+之后,PHP中的所有函数都是从Closure类创建的对象。使用RFC可以让代码更加简洁明了functionaddTo($a){returnfunction($b)use($a){return$a+$b;};}$filter=function(callable$f):Container{returnContainer::of(call_user_func($f,$this->_value)?$this->_value:0);};$wrappedInput=Container::of(2);$validatableContainer=$filter->bindTo($wrappedInput,Container);$validatableContainer('is_numeric')->map(addTo(40));//输出->42$wrappedInput=Container::of('abc);$validatableContainer('is_numeric')->map(addTo(40));//output->40解释了本书的详细内容和例子。点击链接FunctionalPHP,函数式编程的组合包FunctionalPHP:FunctionalprimitivesforPHP{"require":{"lstrojny/functional-php":"~1.2"}}本质上,我还没有读完这本书,而且很多地方翻译都没有表??达意思。还是结合实际例子一一理解。本文将在后面继续补充和讨论。额外的学习经验。去PHP!