你真的了解php吗?

一、特性

1. 命名空间

命名空间用的比较多,不详细写了,记录几个值得注意的实践和细节。 多重导入 别这么做,这样写容易让人困惑。

<?php
use Symfony\HttpFoundation\Request,
    Symfony\HttpFoundation\Rese,
    Symfony\HttpFoundation\Cookie;

建议一行写一个use语句:

<?php
use Symfony\HttpFoundation\Request;
use Symfony\HttpFoundation\Rese;
use Symfony\HttpFoundation\Cookie;

一个文件中使用多个命名空间 你可以这么做,但这违背了“一个文件定义一个类”的良好实践。

<?php
namespace Foo {  
//code
}namespace Bar {  
//code 
}

全局命名空间 想要使用PHP原生的Exception类,需要在类名前加 \ 符号。

<?php
namespace My\App;
class Foo{  
public function doSomething()
  {
    $exception = new \Exception();
  }
}

如果Exception前不加 \ 符号,会在My\App命名空间下寻找Exception类。

2. 使用接口

使用接口编写的代码更灵活,能委托其他人实现细节。使用的人只需要关心有什么接口,而不需要关心实现。能够很好地解耦代码,方便扩展,比较常用就不说啦。

3. 性状

在学习laravel框架之前都没弄清楚性状(trait)。这是PHP5.4.0引入的新概念,既像类又像接口。但它两个都不是。

性状是类的部分实现,可以混入一个或多个现有PHP类中。类似Ruby的组合模块活混入(mixin)。

为什么使用性状 举个具体的例子,比如有两个类,Car 和 Phone,他们都需要GPS功能。为了解决这个问题,第一反应创建一个父类,然后让Car和Phone继承它。但因为很明显,这个祖先不属于各自的继承层次结构。

第二反应创建一个GPS的接口,定义好GPS的功能接口,然后让Car和Phone两个类都实现这个接口。这样做能实现功能,同时也能保持自然的继承层级结构。不过,这就使得在两个都要实现重复的GPS功能,这不符合DRY(dont repeat yourself)原则。

第三反应创建实现GPS功能的性状(trait),然后在Car和Phone类中混入这个性状。能实现功能,不影响继承结构,不重复实现,完美。

创建与使用性状 创建trait

<?phptrait MyTrait{ 
//实现
}

使用trait

<?php
class MyClass{  
use MyTrait;  
// 类的实现
}

4. 生成器

PHP生成器(generator)是PHP5.5.0引入的新功能,很多PHP开发者生成器不了解。生成器是个简单的迭代器,但生成器不要求实现Iterator接口。生成器会根据需要计算并产生要迭代的值。如果不查询,生成器永远不知道下一个要迭代的值是什么,在生成器中无法后退或快进。具体看如下两个例子:

简单的生成器

<?php
function makeRange($length) {  
  for ($i = 0; $i < $length; $i++) {    
    yield $i;
  }
}
foreach (makeRange(1000000) as $i) {  
echo $i, PHP_EOL;
}

具体场景:使用生成器处理CSV文件

<?php
function getRows($file) {
  $handle = fopen($file, 'rb');  
   if ($handle === false) {    
    throw new Exception();
  }  
 while (feof($handle) === false) {    
    yield fgetcsv($handle);
  }
}
foreach (getRows('data.csv') as $row) {
  print_r($row);
}

处理这种场景,习惯的处理方法是先读取文件的所有内容放到数组中,然后再做处理等等。这种的处理存在的问题是:当文件特别大,一次读取就占用很多内存资源。而生成器最适合这种场景,因为这样占用的系统内存量极少

5. 闭包

理论上,闭包和匿名函数是不同的概念。不过,PHP将其视作相同的概念。 简单闭包

<?php
$closure = function ($name) {  
    return sprintf('Hello %s', $name);
}
echo $closure("Beck");
// 输出 --> “Hello Beck”

注意:我们之所以能调用$closure变量,是因为这个变量的值是个闭包,而且闭包对象实现了__invoke()魔术方法。只要变量名后有(),PHP就会查找并调用__invoke()方法。

附加状态 使用use关键字可以把多个参数传入闭包,此时要像PHP函数或方法的参数一样,使用逗号分隔多个参数。

<?php
function enclosePerson($name) {  
 return function ($doCom) use ($name) {    
    return sprintf('%s, %s', $name, $doCom);
  };
}// 把字符串“Clay”封装在闭包中
$clay = enclosePerson('Clay');
// 传入参数,调用闭包echo $clay('get tea!');
// 输出 --> "Clay, get tea!"

6. Zend OPcache

字节码缓存不是PHP的新特性,很多独立的扩展可以实现缓存。从PHP5.5.0开始,PHP内置了字节码缓存功能,名为Zend OPcache。

字节码缓存是什么 PHP是解释性语言,PHP解释器执行PHP脚本时会解析PHP脚本代码,把PHP代码编译成一系列Zend操作码,然后执行字节码。每次请求PHP文件都是这样,会消耗很多资源。字节码缓存能存储预先编译好的PHP字节码。这意味着,请求PHP脚本时,PHP解释器不用每次都读取、解析和编译PHP代码。这样能极大地提升应用的性能。

7. 内置的HTTP服务器

从PHP5.4.0起,PHP内置了Web服务器,这对众多使用Apache或nginx的php开发者来说,可能是个隐藏功能。不过,这个内置的服务器功能并不完善,不应该在生产环境中使用,但对本地开发来说是个便利的工具,可以用于快速预览一些框架和应用。

启动服务器

php -S localhost:4000

配置服务器

php -S localhost:8000 -c app/config/php.ini

路由器脚本 与Apache和nginx不同,它不支持.htaccess文件。因此,这个服务器很难使用多数流行的PHP框架中常见的前端控制器。PHP内置的服务器使用路由器脚本弥补了这个遗漏的功能。处理每个HTTP请求前,会先经过这个路由器脚本,如果结果为false,返回当前HTTP请求中引用的静态资源URI。

php -S localhost:8000 route.php

是否为内置的服务器

<?php
if (php_sapi_name() === 'cli-server') {  
// php 内置的web服务器
}

原文发布于微信公众号 - php(phpdaily)

原文发表时间:2017-02-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏晨星先生的自留地

finecmsV5.0.8写文件漏洞分析

2012
来自专栏跟着阿笨一起玩NET

Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的区别!

         这个方法通过程序集的长名称(包括程序集名,版本信息,语言文化,公钥标记)来加载程序集的,会加载此程序集引用的其他程序集,一般情况下都应该优先...

571
来自专栏mySoul

微信小程序自定义组件(二)

两个<custom-ul>以及<custom-li>两个组件都为自定义组件,如果进行通信会非常的难以操作,至此通过relations完成子父组件的定义,简化通信...

1003
来自专栏流媒体

linux下Socket编程(一)简介

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”...

802
来自专栏不想当开发的产品不是好测试

常用业务接口界面化 in python flask

背景: 对于业务测试来说,有一些基础业务接口是需要经常调用的,如根据userId查询某人的信息,修改某人的xx属性,一般的接口都有验签(或者说token)机制,...

19610
来自专栏Jed的技术阶梯

Kafka 新版消费者 API(二):提交偏移量

最简单的提交方式是让消费者自动提交偏移量。如果 enable.auto.commit 被设为 true,那么每过 5s,消费者会自动把从 poll() 方法接收...

1772
来自专栏Django Scrapy

倒排索引

主楼搜索引擎的主流算法 倒排索引源于实际应用中需要根据属性的值来记录,这种只能怪索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录开...

3536
来自专栏非著名程序员

Html或JS语法检测之JSLint工具

1、介绍 JSLint是一个JavaScript验证工具(非开源), 可以扫描JavaScript源代码来查找问题。如果JSLint发现一 个问题,JSLin...

1947
来自专栏七夜安全博客

BaseProxy:异步http/https代理

1134
来自专栏机器学习从入门到成神

JSP页面跳转的几种方法以及注意点

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

1250

扫码关注云+社区