Modern PHP 笔记(一):语言特性

系列笔记:
Modern PHP 笔记(一):语言特性
Modern PHP 笔记(二):良好实践
Modern PHP 笔记(三):部署测试和调优

现在正式加入世界上最好的语言大家庭了。jimbochen大佬给推荐了 Josh Lockhart 写的,安道翻译的《Modern PHP》. 准备记录下一些学习笔记。刚刚入坑,如果理解的不对,欢迎指出。

这本书刚看,觉得内容很扎实。对PHP的整个生态有了更深的理解。强烈推荐读一下。顺便吐槽下,简书的markdown不支持toc,这个蛮影响体验。

第一章:新时代的PHP

PHP正在重生,得益于命名空间、性状、闭包和内置的操作码缓存等有用的特性

现状

跳出了框架的束缚,依赖composer管理插件,混搭合适的组件。

历史

  • 创始人:拉斯姆斯·勒多夫
  • PHP tools:Personal Home Page Tools
  • 1998年,PHP3: PHP: Hypertext Preprocessor
  • PHP引擎: Zend Engine、HipHop Virtual Machine
  • 基于PHP之上的语言:Hack

第二章:特性

命名空间

目的:避免命名冲突

使用命名空间

    // 声明命名空间
    namespace Oreilly\ModernPHP;
    // 厂商命名空间最重要,必须具有全局唯一性

    // 导入类和别名
    use Symfony\Component\HttpFoundation\Response as Res;

    // 导入函数
    use func Namespace\functionName;

    // 导入常量
    use constant Namespamce\CONST_NAME;

全局命名空间

    <?php
    namespace My\App;

    class Foo
    {
        public function doSomething()
        {
            $exception = new Exception();
        }
    }

Exception类没有命名空间,在全局命名空间中,此时调用\My\App\Foo::doSomething()
报错。
正确写法为:new \Exception()

使用接口

接口是两个PHP对象之间的契约,其目的不是让一个对象依赖另一个对象的身份,而是依赖另一个
对象的能力。我们不关心第三方代码如何实现接口,只关心是否实现了指定接口。

    // 操作的入参Documentale不是类,是接口
    class DocumentStore
    {
        public function addDocument(Documentable $document)
        {
            ...
            $document->getId();
            $document->getContent();
        }
    }

    // 接口定义
    interface Documentable
    {
        public function getId();

        public function getContent();
    }


    // 类1实现了接口
    class HtmlDocument implements Documentable
    {
        public function getId()
        {
            // ...
        }

        public function getContent()
        {
            // ...
        }
    }

    // 类2实现了接口
    class StreamDocument implements Documentable
    {
        public function getId()
        {
            // ...
        }

        public function getContent()
        {
            // ...
        }
    }

性状trait

性状有两个作用:表明类可以做什么(像接口),提供模块化实现(像类)

为什么使用性状

继承模型不好用时,比如想让两个无关的PHP类具有类似的行为?(e.g.零售店类和汽车类都想使用
地理编码转换成经纬度功能时)

  1. 方案一:继承共同父类。——不好。让两个无关类继承自同一祖先。
  2. 方案二:创建地理转换接口。——好一点。但是两个类都需要实现相同的代码,不符合DRY原则
  3. 方案三:使用性状,直接在两个类中混入性状——最好

创建性状

    <?php
    trait MyTrait {
        // 这里写性状实现
    }

使用性状

    class MyClass
    {
        use MyTrait;
        // 类其他实现
    }

PHP会直接把性状代码粘贴在类中,因此要注意兼容问题。

生成器generator

生成器是简单的迭代器。不同的是,不要求类实现Iterator接口,每次只计算下一个值,不会在内存
中预先计算。提升性能

创建生成器函数

  • 是的,生成器是使用了yield关键字的函数。

  • 只产出值,不返回值。

  • 返回一个属于Generator类的对象,可以用foreach()迭代。

  • 生成器每产生一个值内部状态就会停顿,然后恢复,停顿...

      function myGenerator()
      {
          yield 'value1';
          yield 'value2';
      }
    

使用生成器

常用于需要节省内存时,比如生成一个大范围的数、处理很多行的csv文件等。

    foreach (myGenerator() as $yieldValue) {
        echo $yieldValue, PHP_EOL;
    }

闭包

  • 闭包是创建时封闭周围状态的函数。即便闭包所在环境不存在了,闭包中封装的状态依旧存在。
  • 匿名函数时没有名称的函数,非常适合作为函数或方法的回调。

PHP中将闭包和匿名函数视为相同概念。

创建闭包

与函数语法相同,但实际上闭包是Closure类的实例,不是函数。

附加状态

必须调用闭包对象的bindTo()方法或者使用use关键字,将状态附加到PHP闭包上。

    $que = function ($query)use ($id) {
        // $id是外面变量
    }

bindTo()方法将闭包实例的内部状态绑定到其他对象上,则闭包可以访问绑定闭包的对象中受保护方法和私有成员变量。

e.g.,PHP框架经常使用bindTo()方法把路由URL映射到匿名函数。因此可以在匿
名函数中使用$this引用应用对象。

Zend OPcache 字节码缓存

PHP是解释型语言,PHP解释器执行PHP脚本时会解析代码,将其编译成 Zend 操作码,然后执行
字节码。每次HTTP请求都会不断解析、编译、执行。缓存字节码可以节省时间,提高性能。

Zend OPcache 默认不启用,需要手动开启并配置。

内置HTTP服务器

从PHP 5.4 开始

启动内置服务器

    // 根目录
    php -S localhost:4000

自定义配置

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

路由器脚本

内置的服务器不支持.htaccess文件,因此很难使用前端控制器。

前端控制器是一个PHP文件,用于转发所有的HTTP请求(通过.htaccess文件或者重写规则实现)。
前端控制器的职责是,分发请求,以及调度适当的PHP代码。

内置服务器使用路由脚本弥补这个功能。处理HTTP请求前,先执行路由器脚本,如果为false,则
返回请求的静态资源URI,否则返回脚本的执行结果。

    php -S localhost:8000 router.php

判断使用哪种服务器

    if (php_sapi_name() === 'cli-server'){
        // PHP 内置的服务器
    } else {
        // 其他 Web 服务器
    }

缺点

不能用在生产环境:

  • 一次只能处理一个请求
  • 只支持少量媒体类型
  • 通过路由器脚本支持少量URL重写规则,更高级不行

更多笔记还在读书中O(∩_∩)O哈哈~

最后,照例记录下一段很喜欢的话共勉。

过一个平凡无趣的人生实在太容易了,你可以不读书,不冒险,不运动,不写作,不外出,不折腾……但是,人生最后悔的事情就是:我本可以。  ——陈素封
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 148,827评论 1 317
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 63,511评论 1 266
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 99,318评论 0 218
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,108评论 0 189
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,112评论 1 266
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,387评论 1 185
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,905评论 2 283
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,657评论 0 177
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,144评论 0 223
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,744评论 2 225
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,100评论 1 236
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,565评论 2 222
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,041评论 3 216
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,769评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,301评论 0 178
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,173评论 2 239
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,313评论 2 242

推荐阅读更多精彩内容

  • Composer Repositories Composer源 Firegento - Magento模块Comp...
    零一间阅读 3,936评论 1 66
  • 内存是计算机非常关键的部件之一,是暂时存储程序以及数据的空间,CPU只有有限的寄存器可以用于 存储计算数据,而大部...
    dreamer_lk阅读 1,109评论 2 10
  • ziadoz在 Github发起维护的一个PHP资源列表,内容包括:库、框架、模板、安全、代码分析、日志、第三方库...
    Gundy_阅读 6,208评论 4 192
  • 补昨天 去姑姑家吃饭 见姐姐和bb 现在的小孩竞争好大 姐姐压力也很大 bb一直拉着我讲他的飞机 看着他们感觉要思...
    rrreason阅读 97评论 0 0
  • 你知道么? 国庆节,一个港星过生日,郑伊健。 Sir想问问: 在80后记忆里,他什么样? 是《古惑仔》气势逼人的大...
    Sir电影阅读 828评论 1 10