45道求职不可错过的PHP面试题(上)Q28:你会如何使用PHP创建一个单例类?/***单例类**/finalclassUserFactory{/***调用此方法获取单例**@returnUserFactory*/publicstaticfunctionInstance(){static$inst=null;如果($inst===null){$inst=newUserFactory();}返回$inst;}/***privatector所以没有其他人可以实例化它**/privatefunction__construct(){}}如何使用:$fact=UserFactory::Instance();$fact2=用户工厂::实例();但是:$fact=newUserFactory()抛出一个错误。Q29:PDO的query()和execute()有什么区别?query运行标准SQL语句,并要求您正确转义所有数据以避免SQL注入和其他问题。execute运行一个准备好的语句,允许您绑定参数以避免转义或引用它们。如果多次重复查询,execute也会执行得更好。最佳做法是坚持准备好的语句并执行以提高安全性。preparedstatements除了在客户端提供转义能力外,在服务端也会编译一次,然后每次执行时可以传递不同的参数。Q30:空合并运算符的用途是什么?空合并运算符将返回其第一个操作数(如果存在),而不是NULL。否则,它返回它的第二个操作数。示例:$name=$firstName??$用户名??$占位符??“客人”;Q31:区分异常和错误错误无法恢复。错误的唯一解决方案是终止执行。异常您可以通过使用try-catch块或将异常抛给调用者来从中恢复。您将无法使用try-catch块处理错误。即使使用try-catch块处理它们,应用程序也无法恢复。另一方面,可以使用try-catch块处理异常,如果发生异常,可以使程序正常运行。异常是与错误运行应用程序的环境相关的应用程序。Q32:什么是异常类函数?Exception类中提供了以下函数。getMessage()?异常消息getCode()?异常代码getFile()?源文件名getLine()?源代码行getTrace()?n数组backtrace()getTraceAsString()?格式化跟踪字符串Exception::__toString给出字符串表示的异常。Q33:参数化函数和非参数化函数的区别非参数化函数在调用时不接受任何参数。参数化函数在调用时采用一个或多个参数。当输出取决于运行时给出的动态值时,它们可以在程序运行时使用。有参函数的访问方式有两种:Callbyvalue:(这里直接传值)Callbyreference:(这里传值存放的地址位置)通过引用,如果在函数内部修改了实际值,就会被修改。在这种情况下,我们需要使用带有形式参数的&符号。&表示可变引用。例子:functionadder(&$str2){$str2.='CallByReference';}$str='这是';加法器($str);回声$海峡;output:ThisisCallByReferenceQ35:为什么我们要使用extract()?extract()函数将数组中的变量导入本地符号表。该函数使用数组键作为变量名,值作为变量值。对于每个元素,它将在当前符号表中创建一个变量。此函数返回成功提取的变量数。例子:$a="Original";$my_array=array("a"=>"Cat","b"=>"Dog","c"=>"Horse");extract($my_array);echo"\$a=$a;\$b=$b;\$c=$c";输出:$a=猫;$b=狗;$c=HorseQ36:解释什么是PHP闭包以及它为什么使用“use”标识符?考虑以下代码:publicfunctiongetTotal($tax){$total=0.00;$callback=function($quantity,$product)use($tax,&$total){$pricePerItem=constant(__CLASS__."::PRICE_".strtoupper($product));}$总计+=($pricePerItem*$quantity)*($tax+1.0);};array_walk($this->products,$callback);返回回合($总计,2);你能解释一下为什么使用它吗?这就是PHP表示闭包的方式。基本上,这意味着您允许匿名函数在其范围之外“捕获”局部变量(在本例中为$tax并引用$total)并保留它们的值(或者在$total的情况下,引用$totalitself))作为匿名函数本身内部的状态。闭包是一个单独的命名空间,通常,您不能访问在该命名空间之外定义的变量。use允许您访问(使用)闭包内的后续变量。使用是早期绑定。这意味着在定义闭包时会复制变量值。所以在闭包内部修改$tax没有外部影响,除非它是一个类似于对象的指针。您可以像&$total一样将变量作为指针传递。因此,修改$totalDOES的值具有外部效果,即更改原始变量的值。Q37:PHP最新的静态绑定是什么?基本上,归结为self关键字不遵循相同的继承规则。self总是解析为使用它的类。这意味着如果您在父类中创建一个方法并从子类中调用该方法,self将不会像您期望的那样引用子类。后期静态绑定通过引入static关键字的新用途解决了这个特殊的缺点。当你使用静态时,它代表你第一次使用它的类,即。它“绑定”到运行时类。考虑:classCar{publicstaticfunctionrun(){returnstatic::getName();}privatestaticfunctiongetName(){return'Car';}}classToyotaextendsCar{publicstaticfunctiongetName(){return'Toyota';}}echoCar::run();//输出:CarechoToyota::run();//输出:ToyotaQ38:如何测量PHP脚本的执行时间?我想知道执行PHPwhile循环需要多少毫秒。你能帮我吗你可以使用这个microtime功能。考虑:$start=microtime(true);while(...){}$time_elapsed_secs=microtime(true)-$start;Q39:合并两个PHP对象的最佳方法是什么?//Wehavethis:$objectA->a;$objectA->b;$objectB->c;$objectB->d;//我们想要最简单的方法得到:$objectC->a;$objectC->b;$objectC->c;$objectC->d;这有效:$obj_merged=(object)array_merge((array)$obj1,(array)$obj2);您还可以使用array_merge_recursive来实现深度复制行为。另一种方法是:foreach($objectAas$k=>$v)$objectB->$k=$v;这比<7个版本的PHP中的第一个答案更快(估计快50%)。但在PHP>=7中,第一个答案快了400%。Q40:比较mysqli或PDO-优缺点是什么?让我们给它命名:PDO是标准,也是大多数开发人员期望使用的标准。将应用程序从一个数据库迁移到另一个数据库并不常见,但迟早您会发现自己正在使用不同的RDBMS处理另一个项目。如果您在家中使用PDO,那么到那时至少可以少学一件东西。使用PDO的真正好处是您可以获取数据并将其自动注入到对象中。PDO具有一些有助于SQL注入的特性,从执行速度的角度来看,MySQLi胜出,但除非你有一个很好的MySQLi包装器,否则它在处理准备好的语句方面很糟糕。插入-几乎相等,选择-mysqli对于非准备语句快2.5%,对于准备语句快6.7%。Q41:飞船操作员的目的是什么?<=>运算符会提供组合比较,因为它会:如果两边的值相等则返回0,如果左边的值更大则返回1,如果右边的值更大则返回-1考虑://比较Integersecho1<=>1;//输出0echo3<=>4;//输出-1echo4<=>3;//输出1//字符串比较echo"x"<=>"x";//0echo"x"<=>"y";//-1echo"y"<=>"x";//1Q42:PHP有线程吗?标准php不提供任何多线程功能,但实际上有一个(实验性的)扩展-pthreads。下一个最好的办法是让一个脚本通过CLI执行另一个,但这有点基础。根据您尝试做的事情以及它的复杂程度,这可能是正确的,也可能不是正确的。Q43:PHP是单线程还是多线程?PHP本身并不是单线程的。然而,在这种情况下,Unix系统上最常见的PHP安装是单线程的,最常见的Apache安装也是如此,而nginx没有基于线程的架构。在大多数常见的Windows设置和一些更高级的Unix设置中,PHP可以并且确实在单个进程中的多个解释器线程上运行。自2000年以来,PHP作为解释器就支持多线程。Q44:提供一些方法来模拟PHP中的多个构造函数众所周知,您不能在PHP类中放置两个具有唯一参数签名的__construct函数,但我想这样做:classStudent{protected$id;受保护的$名称;//等等publicfunction__construct($id){$this->id=$id;//其他成员仍未初始化}publicfunction__construct($row_from_database){$this->id=$row_from_database->id;$this->name=$row_from_database->name;//等}}使用PHP实现此目的的最佳方法是什么?我可能会做这样的事情:$instance->loadByID($id);返回$实例;}publicstaticfunctionwithRow(array$row){$instance=newself();$instance->fill($row);返回$实例;}protectedfunctionloadByID($id){//做查询$row=my_awesome_db_access_stuff($id);$this->fill($row);}protectedfunctionfill(array$row){//填充数组中的所有属性}}然后,如果我想要一个我知道ID的学生:$student=Student::withID($id);从技术上讲,你不需要构建多个构造函数,而只是构建静态辅助方法,但这样你就可以避免在构造函数中出现大量的意大利面条式代码另一种方法是结合工厂风格和流畅风格:classStudent{protected$firstName;受保护的$姓氏;//等等/***构造函数*/publicfunction__construct(){//分配你的东西}/***静态构造函数/工厂*/publicstaticfunctioncreate(){$instance=newself();返回$实例;}/***FirstNamesetter-流畅风格*/publicfunctionsetFirstName($firstName){$this->firstName=$firstName;返回$这个;}/***LastNamesetter-流畅风格*/publicfunctionsetLastName($lastName){$this->lastName=$lastName;返回$这个;}}//创建实例$student=Student::create()->setFirstName("John")->setLastName("Doe");Q45:如何在PHP中实现方法重载?您不能重载PHP函数。函数签名仅基于它们的名称,不包括参数列表,因此您不能拥有两个同名的函数。但是,您可以声明一个接受可变数量参数的可变参数。您将使用func_num_args()和func_get_arg()获取参数并正常使用它们。考虑:functionmyFunc(){for($i=0;$i
