浏览作者: panlatent

我是潜伏的胖子 ——— 一个喜欢编程,并钟情于PHP的程序员。我十分确定PHP在Web上的葱郁的生命力,并对PHP在Web之外的表现力非常关注与期待。潜伏的博客中的潜伏二字出自”潜伏的胖子”,而”潜伏的胖子”具体出处已不可考。博客以潜伏命名,是希望自己能够平凡踏实的研究技术,默默地分享与收获。鉴于网络很多同质化的内容,虽然有利于知识的传播与普及,但是如果直接拿来生搬硬套,可能就会出现一些问题。我坚持写原创技术博客,把自己对技术的理解,实现和遇到的问题分享给大家。这样既可能给出现过同样问题的人一定思路和建议,也能够使自己的思想和技术沉淀下来。

PHPStorm 2017.1 中的新功能

PHPStorm 无疑是开发 PHP 项目的神器,秉承着 JetBrains 家族的优良传统,是用来写世界上最好的语言的不二选择。在今天迎来了最新的 2017.1 版本,一接到通知邮件,我就迫不及待的更新了新版本,并查看了新特性,整理成中文分享给大家。

点击进入 PHPStorm 官网

亮眼的新封面

概览

  • Codeception 支持
  • PHPUnit 6 支持
  • 参数提示
  • 更好的 PRS-0 支持
  • 字符串形式的 PHP 类名解析
  • 改进 PHP 代码风格
  • 更好的自动导入
  • PHP 7 统一变量语法
  • 当前作用域突出显示
  • 更好的 PHP 7.1 支持
  • 新代码高亮
  • PHP 运行时配置
  • 新的检查
  • PHP 调试
  • Web 技术
  • IDE 改进
  • 数据库工具

工具和框架支持

支持 Codeception 全栈测试框架

PhpStorm 现在支持 Codeception 测试框架(从 2.2.0版本开始)。你能从 Composer 或者 PHAR 安装它。 PhpStorm运行配置将帮助你在本地运行测试, 测试目标可以在一个 Vagrant 虚拟机上, 也可以在远端解释器或者Docker上.

支持 PHPUnit 6

最近,PHPUnit 6 已经发布,现在我们将在PhpStorm中支持它。在新的PhpStorm中,新的命名空间 TestCase 类是被认可和支持的。

改进 Blade 模版引擎的支持

这对 Laravel 开发者是一个好消息: PHPDoc 在 Blade injections 中被支持. 你可以在模板内提供变量类型以使用代码补全。. 其他改进包括支持 @includeWhen, @component, 和 @slot directives 嵌套在文档结构中。

编辑体验

参数提示( Parameter hints )

参数提示是显示在方法的参数值前面的文字,帮助你更好的理解语义的具体方法。我们还增加了一个选项来定制你的内联参数提示,以符合你的IDE配色方案。感谢PhpStorm的参数提示,代码变得更具可读性,更容易理解。

更好的支持 PSR-0 和重命名/重构功能

现在,如果你在psr-0根目录使用重命名重构功能,它也改变了你的类的命名空间,反之亦然。此外,重命名/重构功能会重命名类子类和它们的文件。

PS: 简单来说就是当你修改命名空间,IDE会帮助你修改目录;当你你修改目录,IDE会帮助你修改命名空间。这种修改也包括子类和它们的文件。

识别字符串中PHP类名

PhpStorm 2017.1 在字符串中识别 PHP 类名。类引用将被添加到单引号风格的字符串文字中,这将帮助您在重命名重构中维护正确的名称,并更快地导航到类。

改进 PHP 代码风格

PhpStorm 2017.1 带来了新的有用的代码样式选项,例如:

会在配置选项里显示当前配置是数据全局( IDE )还是项目 ( Project )
声明声明内的可配置空间
为构造函数设置括号 ()
else if 和 elseif 的相互转换
命名空间前的空行

改进自动导入功能

自动导入函数和常量

PhpStorm 2017.1 现在可以自动导入函数和常量。为了使用这一点,去设置选项 Editor | General | Auto Import | PHP 中启用 auto-importfile scope 或是 namespace scope

从全局命名空间自动导入

As an alternative to auto-importing functions and constants from the global namespace, you can ask the IDE to use global references. You can find this option in Settings

作为从全局命名空间自动导入函数和常量的替代方法,可以让IDE使用全局引用。这个选项在设置选项 Editor | General | Auto Import | PHP 中启用 Prepend functionsconstants from the global space with ‘\’.

PHP 语言支持

完全支持 PHP 7 统一变量语法

PhpStorm 2017.1 根据 PHP RFC: Uniform Variable Syntax 带来了改进的 PHP 7 统一变量语法。例如 isset/unsetfoo()()().., 和 $some->foo()() 风格的调用现在被支持。

替代语法的当前范围高亮显示 Current scope highlighting for alternative syntax

在当前作用域内,类似于大括号的替代语法语句现在被高亮显示。现在你可以很容易地查看和导航在 pHTML 模板之间的匹配内容。

PHP 7.1: 改进的匿名类支持

我们增加了对匿名类的支持,这些类现在有一个适当的类型,这意味着匿名类的方法将被正确地解释。这解放了phpStorm的全部力量,包括代码检查,寻找用法,重命名重构,导航到声明和更多内容。

新代码高亮

PhpStorm 2017.1 为所有 extended/implemented 方法、使用 use 导入、或是抛出一个异常(例如 try, catch, 和 @throws)带来了新的醒目的提醒。这样你的代码更直观,更容易掌握重要的细节。要使用此功能,只需将插入 extendsimplementsuse, catch 或者 @throws

配置 PHP 运行时

在 PhpStorm 2017.1 中,可以配置在项目中使用的 PHP 扩展。这将有助于保持完成列表整洁,只包含相关 PHP 拓展项目。

代码质量分析

检测和转换 PHP 4 样式的构造函数到 PHP 5.3 +

Since PHP 4 constructors have been deprecated in PHP 7, we’ve added a new inspection to help detect and convert such constructors to PHP 5.3+ style –__construct. You can also press Alt+Enter for a related quick-fix.

因为 PHP 4 的构造函数已经在 PHP 7 中兼容,我们增加了一个新的检查来帮助检测和转换构造函数到 PHP 5.3 以上的风格 __construct。您也可以按 ALT + Enter 进行编辑位置相关的快速修复。

对于未定义变量的快速修复

添加了新的快速修复功能帮助解决未定义的变量,将其声明为 use 在闭包中导入。

PHP 调试

在调试器中将用户定义常量的分组

现在,所有用户定义的常量都在变量列表中的常量节点下进行分组,这有助于减少干扰并保持变量列表的整洁。

允许选择 IP 发送到 Zend Debugger

PhpStorm 2017.1 自动检测主机的 IP 发送给 Zend Debugger 。当你在具有多个 IP 的机器工作时是特别重要的。如果你使用 Vagrant/VirtualBox/VPN. 您也可以禁用复选框,并且手动提供 IP 。这个选项可以在设置选项中的 PHP | Debug | Automatically 手动设置 IDE IP.

热门 Web 技术支持

Vue.js 支持

享受 Vue 模板语言和您所选择语言的脚本,以及 .vue 文件样式块的编码协助。IDE自动完成 Vue 组件和添加依赖导入。我们刚刚开始!

集成 Jest

感谢新的 Jest 集成,你现在可以从 IDE 运行 Jese 测试,在一个方便的树状视图查看测试结果,从那里轻松地导航到测试源,还调试 Jest 测试。

package.json 模块完成

PhpStorm 现在能在项目的 package.json 文件提取出包名, 并显示描述和新版本。

IDE 改进

版本控制

版本控制附带以下更改:

  • 更新 Git 和 Mercurial 的日志查看器
  • Diff 对话框 中调用 Ignore imports and formatting (忽略导入和格式化) 的新选项。
  • 性能更快的 Git 文件历史

路径搜索

早先的在 Find in Path 中,搜索 预览 选项卡中的 路径查找 对话框已回炉重做,现在首先显示即时结果。 更重要的是,现在您可以通过按 Enter 键在编辑器中打开任何选定的结果。 要在工具窗口中查看结果,请单击底部的按钮或按 Ctrl Enter( Mac OS X 的 Cmd-Enter )。

数据库工具

数据库工具的改进

在 PhpStorm 中的数据库工具已得到改善,感谢我们在 JetBrains datagrip 团队的同事:

  • CSV 导入中的字段映射和 DDL 预览
  • 在 CSV 中导入 С 柱映射和DDL预览
  • 使用拖放操作来导出/导入表
  • SQL 解析范围
  • 尊重默认搜索路径

感谢你的阅读!本文系原创文章,出自 行间小筑 并遵循 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证),转载时请注明出处和本文链接:https://panlatent.com/archives/phpstorm-2017-1-features

博客优化历程

行间小筑使用了著名的建站程序WordPress,并且在最初的便使用了由沃通提供的免费SSL证书。在博客的添加功能、维护与调优的过程中不免会遇到大大小小的问题,所以我在这里会持续更新我是如何解决博客的一些问题。注意,我不会在这篇文章里放置大量的实现代码,更多的会描述解决问题的过程。

行间小筑有的本地(开发测试)和线上(运营)二个版本,使用Git作为版本控制工具并托管到Coding.net。线上版本的文件权限是较小的,这样我的所有插件、主题以及WordPress的安装与更新,都需要通过本地来进行,再提交到Git并在服务端拉取,开发过程十分简单方便而且条理清晰。在建立博客的几周之后我建立了一个自有插件,专门用于给博客添加一些功能和改变一些原有功能,配合其他插件一起完成博客的所有功能。建立一个自有插件是十分必要的,我们无需修改WordPress核心(修改WordPress核心是愚蠢且糟糕的,除非你真的确定非这样做不可),WordPress强大的拓展机制足以让我们的插件覆盖到整个博客的任何角落。将自己开发的功能统一成一个插件十分利于管理和维护。

目前我的博客以自有插件为基础,辅以JetPack(部分功能)、SEO、七牛云、缓存、评论、备份和代码高亮插件,并从一款优秀漂亮的主题派生了自己的主题。

1 针对墙的优化

由于GFW对Google、WordPress、Gravatar.com等网站的封锁,会导致使用Google APIs CDN的WordPress核心、插件和主题的JavaScript、CSS和字体资源无法加载,导致页面响应速度过慢。WordPress的用户头像依赖于Gravatar.com(根据用户的email提供响应的头像服务),而头像图片无法加载也会导致页面响应速度过慢。

所以我们应该从上述几点着手,将主题依赖的Google APIs替换到国内可靠的前端公共CDN上,禁用掉一些被墙的插件功能,如JetPack插件的很多功能依赖wordpress.com/wp.com,我直接关闭了很多功能,只使用我需要的Markdown及其他一些可用的功能。

1.1 替换Google APIs

目前国内有一些前端公共CDN库,如360CDN做到了完全镜像Google APIs,但是它不支持HTTS协议。某些支持HTTPS协议的公共CDN却又没能做到完全镜像,增加了使用的复杂性。如果你的博客是非HTTPS网站,建议直接使用360 CDN。如果你的博客像我一样是HTTPS的,我推荐使用中科大CDN。它支持http(s)的全量Google APIs镜像,你只需要为引用的URL替换host便能够轻松使用。使用说明:https://servers.ustclug.org/2014/07/ustc-blog-force-google-fonts-proxy/

  • 你需要替换WordPress默认使用的Open Sans字体
  • 你需要替换第三方主题可能使用到的Google APIs

1.2 如果你使用Jetpack插件

  • 你需要移除JetPack插件对 devicepx-jetpack.js 引用
  • 仅仅保留你需要的功能,并测试当前启动的功能是否使用了墙外的服务

1.3 关于Gravatar.com头像服务

在我的博客中并没有禁用Gravatar.com头像,一是因为Gravatar.com头像确实非常的方便,能够让我直观的看到评论者的头像;二是修改这一功能需要修改WordPress核心,我认为这是极其糟糕的;三是它对页面响应时间的影响较小,而且我可以为头像做缓存来优化响应时间,所以我并没有禁用这一功能。如果你对禁用Gravatar.com头像感兴趣,可以搜索相关教程。

2 常用插件

2.1 Jetpack

其实安装这个插件最初的目的只是以为了它的Markdown功能十分强大好用,安装完了才发现有好多功能也是比较实用的。这个插件的很多功能都需要链接WordPress使用。如果是在后台还好,若是在前端访问会直接影响到国内用户的加载速度,影响体验,建议禁用这些功能。如果需要,可以使用其他独立的插件替换。Jetpack确实是WordPress下的最强大的插件之一,建议安装。

2.2 SEO

我使用的是all-in-one-seo-pack(多合一SEO集)插件,有关SEO相关配置在这里就不详述了。

我在这个插件里遇到了一个坑,就是这个插件会自动修改404页面标题,需要注意下。

2.3 代码高亮

推荐使用 Crayon Syntax Highlighter 插件, 这款高亮插件选项、代码样式、支持语言十分丰富, 最重要的是通过简单地配置就能够和Markdown插件完美配合。某些高亮插件并不能和Jetpack提供的Markdown功能完美配合(Mardwon 使用三点形式标记代码),会出现代码标签被HTML转译的情况,在不修改插件的情况下只能提前在文章中使用一次[code][/code]形式才能禁止代码符号到HTML的转译,所以推荐这款插件。

2.4 备份

网站的备份我使用了 BackWPup 插件,这个插件能自定义自由度非常高的备份任务,可以被分到文件夹、FTP、Dropbox、Amazon S3、Microsoft Azure、Rackspace Cloud Files、SugarSync和E-Mail,备份内容和打包格式也可以配置。这个插件的备份方式有5种: 手动、借助WordPress的Cron、借助EasyCron.com提供的定时服务触发WordPress的Cron、提供一个用于执行任务的WordPress的Cron链接, 最后一种:利用WP-CLI工具在命令行执行WordPress Cron(该种方式默认支持,不与上面4种方式冲突)。手动备份过于繁琐,剩余3种都过于依赖WordPress提供的基于HTTP请求触发的Cron,任务的执行时间还是具有不确定性,如果你不能使用WP-CLI且不能在你的主机上建立Cron任务,那么我推荐借助EasyCron.com提供的服务来触发WordPress Cron。

WP-CLI的使用方法比较简单,首先下载这个工具并安装,然后在WordPress的目录运行这一命令(wp)就可以了。如果你使用Root用户运行命令, 需要附加 --allow-root 选项。http://wp-cli.org/

安装

在WordPress目录运行

Crontab 计划任务的例子

该任务会在每天的3:00与12:00执行备份, /blog-paht 是我的博客项目在文件系统的路径, 最后的”1″是我建立的backwpup任务的任务号。你可以在WordPress目录使用下面的命令查看任务列表:

3 主题与内容

3.1 放置网站备案号

WordPress中文版是默认支持网站备案号设置, 但是它只能在默认的主题里显示。如果使用第三方主题,可修改主题的footer.php文件中的版权声明区域, 使用 get_option( 'zh_cn_l10n_icp_num' ) 来获得备案号。架设在大陆的个人博客声明备案号还是很有必要的,比较规范的做法是将备案号连接到工信部的查询网站。

3.2 添加第三方统计代码

第三方的统计代码有利于我们监控和分析网站的流量,常用的第三方统计有CNZZ站长统计、百度统计和Google Analytics分析。鉴于Google Analytics被墙,访问速度并不是很明朗的情况,推荐面向国内的博客使用百度统计或站长统计,二者各有优点和差异。我选择了同时使用了百度统计和CNZZ。这样可以让我从各种角度俯瞰我的网站浏览过与受访情况,并能够比对2种统计的差异。我认为这些优点远远的大于加载2种统计带来的微小的加载速度的损失,对访客的体验影响也较小。

我在自己的插件中实现了这一功能。跟放置网站备案号比较类似,我向管理后台的常规设置中添加了一个字段用来保存统计代码,使用 add_filter("wp_footer") 向页面底部添加统计代码。这样做(不是修改主题)的好处是统计代码的功能不依赖于主题。需要注意的是统计代码一般是一些html标签和JavaScript代码,请不要在存取输出的过程中转译它们。

3.3 添加转载版权声明

行间小筑坚持写原创内容,在其中附加转载声明及版权声明有利于在转载的过程中提升博客和原始页面的访问量,这也是对自己写原创的一种激励。如果在每篇文章中都手动注明转载版权声明,显然很麻烦,而且不能进行统一的管理。转载版权声明具有高度的相似性,所以我在自己的插件中实现了这一功能:可以在所有文章列表的快速设置中标记一个文章是原创文章, 在所有可能输出文章内容的地方,如果是原创文章,就按照已经设定好的模板在文章底部附加上转载版权声明。每个声明会附上文章的url,我使用了 str_replace() 函数将模板中 $link 的字符串替换为文章的url。

下面代码只是提示相关功能可能需要用到的钩子名。

3.4 添加分享代码

添加文章的第三方分享功能有助于提高我们的流量,能够给我们带来些额外的用户,而且分享这件事情本身也是很有意义的。专业的事情交给专人去做,这里我们直接使用第三方分享代码。

我仔细的对比了几家第三方代码,只有百度分享的图标样式比较多而且看起来还不是那么老旧。它们的缺点就是不支持HTTPS。让网站支持第三方代码很简单,与添加第三方统计代码和转载版权声明差不多。

为了让我的HTTPS站能够使用HTTPS版本的第三方分享代码,我使用了“代理”的方法让我的博客自动缓存非HTTPS内容,并将静态文件同步至七牛云CDN,有关这个功能的具体开发我将在 代理非HTTPS内容 一节中具体描述。

4 缓存和CDN

行间小筑使用了 W3 Total Cache 作为缓存插件,启用了页面缓存、数据库缓存、对象缓存及浏览器缓存管理,分别存储在Memcache和硬盘上。

我选择使用了七牛云来加速博客的静态文件。因为七牛云每月有一定的免费额度可以使用,足够支撑网站目前以及未来很长一段时间的流量,七牛云CDN的配置也十分简便。最重要的是,七牛云支持部署SSL证书,提供HTTPS访问。这里简要介绍下配置过程:

首先在七牛云建立一个bucket,创建CDN加速并绑定域名 static.panlatent.com, 配置源站为七牛云空间。设置这个bucket镜像源为https://panlatent.com/。(需要注意的是:当bucket镜像的方式工作,只会在第一次没有源文件的情况下会到源站获取文件。除此之外,不会主动刷新文件,除非手动删除镜像文件)

然后可以使用 WPJAM 七牛镜像存储 插件配置CDN加速。具体可以参考插件作者我爱水煮鱼提供的参考PDF《七牛镜像云存储WordPress插件使用指南.pdf》

使用七牛云犯过的错误

  • 更改七牛云CDN的配置时需要很长时间(最久一天)去配置生效,这段时间几乎做不了任何事情,所以初期配置CDN时一定要谨慎。

  • 为了保证CDN资源尽量不被恶意引用(:D 防患于未然),我设置了防盗链功能,但是配置白名单的时候七牛是将 panlatent.com 和 *.panlatent.com 两个配置区别开的,我错写了泛域名导致1天后才能更改和生效正确到配置。

5 有关HTTPS的几点问题

我遇到的HTTPS问题几乎都集中在HTTPS点站对非HTTPS资源的引用上。使用Chrome浏览器,出现这一情况的明显的特征是浏览器开发者调试工具控制台会给出警告,失去小绿锁标志。如果我们能直接替换到HTTPS资源,这是最简单直接的方法。但是很多的非HTTPS资源,例如JavaScript、CSS文件都有其他资源的引入。为了处理这一问题,我为我的博客编写了代理非HTTPS内容的功能,可以实现将网络资源下载并缓存到本地(服务器),并输出内容(按一定规则替换相关引用,原样输出HTTP头)。

5.1 代理非HTTPS内容

后台设置页面
后台设置页面

为了简化调用,我利用了Nginx的重写功能将目录式的URL转换为目标地址的URL参数。在程序获取到目标URL之后,会判断目标Hostname 是否在配置的白名单中(防止恶意调用),如果通过白名单验证,则会询问是否缓存源文件,如果不存在缓存才使用CURL下载远程源文件。然后使用配置的替换规则将可能存在的资源引用替换为代理连接。

一些JavaScript可能存在对非HTTPS的动态请求,如果这些请求不是必要的,在我的插件中可以禁止缓存动态请求的内容,甚至将这些代理的请求伪造为空白内容。这样做可以降低代理功能消耗的资源。

5.2 如何做到引用不支持HTTPS的百度分享

现今的所有国内的第三方分享服务都不支持HTTPS协议,我选择百度分享的主要原因是百度提供的默认图标样式比较统一和美观。百度分享需要在网页引入一段JavaScript代码,去百度加载百度分享的主代码,并且整个分享功能的JS代码是一以模块划分的。此外每次加载分享代码时还会请求一次用于统计的URL。我将默认的分享代码的链接改为 https://panlatent.com/proxy/http/baidu.com 的形式,这样第三方分享功能就会使用我的代理(HTTPS)功能获取到外部资源。我使用了正则将百度网址替换为代理网址的形式,并且专门针对百度分享做了一些特殊的规则。例如,将代理分享统计的请求输出空内容,这样代理功能并不会真的进行资源请求,只是简单的输出空内容。

我尝试了使用七牛云CDN存储我的代理文件,但是尝试了几天失败了。镜像在CDN节点上的百度分享代码模块化加载总是不完全,而由于这些JavaScript代码是经过压缩和精简的,我不太好阅读,另一个原因是因为部署在CDN上的资源刷新需要漫长的时间,即使利用七牛云提供的限额刷新功能,对于调试来说也十分漫长,所以我最终还是使用了源站资源。如果你对此有什么研究和建议,欢迎讨论!我也会不断的尝试实现和优化这一功能。

还有一种方式是直接使用类似七牛云的镜像功能,镜像百度分享。做镜像实际上是比较简单的,但是仍要进行一些简单的字符串替换。为了增强对其他非HTTPS引用的普适性,我并没有使用这种方法。

感言

行间小筑的建立离不开国内云主机的先驱者阿里云提供的云主机,离不开国内证书提供商对SSL免费证书的推广,离不开强大的WordPress,感谢一众博主的技术博客,是他们孜孜不倦且低调内涵的原创内容鼓励着我。进行博客开发的过程使我意识到了对相应场景进行优化开发的重要性。在写作原创文章的过程中,我知道了将脑中知识转换为文字是比较困难,对一个人的知识水平、写作功底、总结能力等都是很大的考验,而且坚持也是十分重要的。我会继续且持续的将我遇到的问题和所感所悟记录在我的博客上,分享给自己,分享给大家。

从没有一个时代可以如此愉快的学习编程,有着如初优厚的资源和环境,有着如此强进的朝气和动力,愿与君努力,用代码 ———— 改变世界!

感谢你的阅读!本文系原创文章,出自 行间小筑 并遵循 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证),转载时请注明出处和本文链接:https://panlatent.com/archives/blog-optimization-process

PHP书籍推荐

有时候读书是一种巧妙地避开思考的方法。 —— 赫尔普斯

推荐之前

最近新买了一本《 PHP Modern 》。在开始阅读的时候,突然感觉书所写与自己近一段时间所作相相印证,有种相见恨晚的感觉。这让我萌生了写一篇PHP书籍推荐博文的想法,我遍历了所有我读完的PHP书籍,选择了几本我认为很优秀的书籍推荐给大家。希望能够给正在PHP初学者或准程序员提供帮助。

对于PHP语言本身来讲,最权威和详细的莫过于官方的英文版参考手册(中文版有很多未翻译的内容,且这些内容并不是最新的)。但是手册只会告诉你有这个东西,参数是什么,有哪些简单的用例。一般不会告诉你为什么有这个东西,为什么这么用,原理是什么。它也不会去讲Web的组件、PHP项目的实践、面向对象编程等等。对于纯粹的PHP内容,我建议书和手册配合学习。书作为一个引导,会告诉你有这样一种东西并且教会你简单的使用。如果我们想要精通,还是要在书籍之外进行深入的学习。

推荐列表

在这里我列出了5本推荐阅读的PHP书籍:

  • 《细说PHP》
    《细说PHP》是国内比较详细的一本PHP入门教程,特点是从前端的 HTML 、 CSS 、JavaScript 到 PHP 都有一个比较详细的入门过程,对PHP介绍的也比较详细。如果你之前没有过 Web 编程或者前端编程经验,建议以这本书入门,它会教会你如何构建一个简单的 Web 程序。(在写作本文章时,该书有中文版,有 Kindle 版)

  • 《PHP和MySQL Web开发》
    《PHP和MySQL Web开发》人称”红宝书”,这是入门 PHP 最经典的一本书籍之一。如果你对 Web 或前端比较熟悉,或者有其他编程经验,可以以这本书入门。这书第一版写于2009年,距现在已经有一段年头了,但其内容仍可称为经典,可以一买。(在写作本文章时,该书有纸质中文版,有 Kindle 版)

  • 《PHP核心技术与最佳实践》
    《PHP核心技术与最佳实践》这本书会讲述PHP在面向对象、数据库、模板引擎、正则匹配、拓展开发、编码风格等方面的最佳实践,内容十分使用。可以称得上是PHP程序员进阶必读之一。(在写作本文章时,该书有纸质中文版,有 Kindle 版)

  • 《深入PHP:面向对象、模式与实践》
    《深入PHP:面向对象、模式与实践》 这本书详述PHP在面向对象方面的一些使用和实践,常用的设计模式和实现过程,作者的功底十分扎实,内容也面面俱到且原理透彻。强烈推荐此书,相信这本书会在你进阶的路上起到极大的帮助。(在写作本文章时,该书有纸质中文版,没有 Kindle 版)

  • 《Modern PHP》
    《Modern PHP》这本书唯一的缺点是来的太迟了。这本书是PHP之道项目的发起者、Slim框架作者所著。它总结的一些现代的PHP程序开发方法、规范和组件,可以说是现在PHP程序员必读的一本书籍。虽然我认为它是必读的,但是这本书并不是一本入门书籍。想完整的吸收这本书的知识,其实需要熟悉PHP语言,熟悉一点现代框架的使用和机制,有过一些项目经验的程序员。但这些也不是绝对,只要你对书中的东西感兴趣,都可以买来阅读。(在写作本文章时,该书有纸质中文版,没有 Kindle 版)

推荐之后

上面的推荐列表仅仅是我个人遴选出的几本书籍,相信还有很多优秀的书籍等待着大家阅读,而且 PHP 之外的世界也同样精彩。感谢这些作者孜孜不倦的努力,给我们带来了这些非同寻常的财富。接下来我会列举其他我阅读过的 PHP 书籍和利用过的资源,希望有所帮助。

书籍 (不含购买链接)

  1. 《深入理解PHP》
  2. 《PHP精粹》
  3. 《高性能PHP应用开发》
  4. 《MySql必知必会》
  5. 《白帽子讲Web安全》
  6. 《HTTP权威指南》
  7. 《Restful Web APIs 中文版》

博客

  1. http://www.laruence.com/ 风雪之隅
  2. http://www.ruanyifeng.com/blog/ 阮一峰的网络日志

资源

  1. https://segmentfault.com/ 一个国内的专注于解决编程问题,提高开发技能的问答社区
  2. http://stackoverflow.com/ 国外著名问答社区
  3. http://wulijun.github.io/php-the-right-way 《PHP之道》中文版
  4. http://www.php-fig.org/ PHP-FIG组织
  5. https://packagist.org/ PHP包仓库(Composer依赖于此)
  6. http://www.oschina.net/ 开源中国
  7. http://www.php100.com/ PHP100
  8. http://www.ituring.com.cn/ 图灵社区

感谢你的阅读!本文系原创文章,出自 行间小筑 并遵循 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证),转载时请注明出处和本文链接:https://panlatent.com/archives/php-book-recommendations

使用PHP编写HTTP服务器

PHP最初作为一个专门为Web开发量身定制的语言,本身提供了底层的语法、函数和机制让我们拥有了超高的Web开发效率,使用PHP就相当于使用其他语言附加上了一个Web框架。我们拥有非常好用的$_GET, $_POST超全局数组,以及非常令人省心的单进程模型:每次请求对应一个进程,让我们无需理会线程安全、微小的内存泄漏和资源的清理。但是这些优点像我们屏蔽了一些底层的细节。追根溯源,回到Web开发的源头,使用PHP实现一个HTTP服务器并且运行PHP业务代码,应该是一件很有趣的事情, 这有助于我们理解HTTP协议和HTTP服务器的工作原理,以及HTTP服务器是怎样与PHP配合工作。

在这篇文章中我将会介绍如何用PHP实现一个可以运行内置Web框架的HTTP服务器。先从如何实现一个Socket服务器接收网络请求开始, 探究如何解析HTTP协议,处理HTTP请求和返回响应。接下来结合多进程拓展实现一个多进程的服务模型, 再结合Libevent实现一个事件驱动的非阻塞网络调用。为了限制请求的数量,实现对资源的合理分配和使用,我们会建立一个工作的进程池来处理请求队列。最后我会使用Symfony/Console编写一个命令行程序和守护进程用来管理HTTP Server。

需要注意的是这个项目仅仅作为PHP Web框架的容器服务器。为了简化开发,这个服务器不会支持完整的HTTP协议,所以会使用Nginx作为反向代理服务器来支持完整的HTTP协议。

一个简单的Socket Server (套接字服务器)

解析HTTP协议

基于Pcntl拓展的多进程工作模型

及时关闭连接

使用libevent事件驱动

多进程工作模型拓展:工作进程池

编写守护进程和命令行参数

使用Nginx作为反向代理服务器

后记

如果你对使用PHP进行网络编程感兴趣,我推荐Workman和Swoole这两个项目。 前者是使用纯PHP代码实现的网络库,后者是韩天峰开发的PHP拓展。二者都支持开发Socket/WebSocket/Http Server。

感谢你的阅读!本文系原创文章,出自 行间小筑 并遵循 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证),转载时请注明出处和本文链接:https://panlatent.com/archives/use-php-compose-http-sever

编写规范的PHP命令行程序: 使用Symfony Console组件

在这篇文章里, 我会先介绍基本的PHP命令行程序开发, 然后再介绍如何使用Symfony/Console组件编写命令行程序, 最后会介绍如何使用Phar打包命令行程序.

1) 基本的命令行程序

1.1) 标准输入和输出

PHP CLI模式下有三个系统常量, 会默认打开3个文件描述符: STDIN, STDOUT, STDERR, 即标准输入, 标准输出和标准错误. 这几个文件描述符与fopen()返回的文件描述符通用, 并且同样可以被关闭. 可以被关闭这一点很重要, 因为有很多的命令行程序并不需要对这几个输入输出设备进行操作, 特别是当命令行程序是多线程(多进程)服务端程序是, 保持他们而不关闭会有一定性能开销.

PHP还支持这三个标准设备流, 即 php://stdin , php://stdout , php://stderr , 这样我们可以使用fopen等函数打开标准设备, 并进行相应操作.

在Web开发中我们使用的echo, print_r, 包括exit() 等输出的字符串均会被送至标准输入设备(STDOUT)在终端中显示. var_dump也能够在终端正确显示被打印的变量. 需要注意的是在终端中使用”\n”换行, 而不是HTML的br标签. 作为命令行程序, 建议只在终端中仅仅显示一些必要的信息, 更多的消息应该写入系统或自定义的日志中.

1.2) 获取当前执行目录

get_pwd() 函数

1.3) 获取命令行参数

1.3.1) $argv 变量

1.3.2) get_options() 函数

1.4) 命令行安全

1.4.1) SAPI 防范

由于命令行基本都是PHP CLI, 也就是用以CLI模式运行. 为了防患于未然, 我们可以检查PHP的运行模式, 防止那些以其他SAPI模式启动PHP程序(特别是CGI/FastCGI/Apache2Handler等)调用我们的命令行程序.

获取SAPI可以通过以下二种方式:
+ php_sapi_name() 函数, 返回接口类型的小写字符串, [php language=”.net”]/php
+ PHP_SAPI 常量, 与php_sapi_name()函数具有相同的值

2) 使用Symfony/Console组件

一个标准的命令行程序一般需要支持长短参数, 查看版本和帮助信息, 查看支持的命令和参数选项等功能. 如果这些功能全部从零构建, 将花费大量时间. 还好我们有Symfony/Console库来帮助我们构建基础的命令行环境, 这样我们就可以专注于命令的功能开发.

使用Symfony/Console组件编写命令行应用和使用框架编写Web Mvc应用很像.

2.1) 约定

3) 使用Phar打包臃肿的命令行程序

无论是自行开发命令行程序, 还是基于Symfony/Console组件, 绝大多数情况下我们都会建立多个php文件. 如果能将这些文件合并成一个文件, 使用和拷贝将十分方便.

如果决定使用Phar打包PHP程序, 最大的问题是如何处理依赖项目. 绝大多数现代的PHP程序都已经使用了Composer作为依赖管理工具. 如果不将依赖项目打包, 则最终phar文件并不能直接使用. 如果打包依赖, 则会造成phar文件过大.

为了解决这个问题, 我开发了一个按需加载的项目(composer-phar). 使用这个项目不会将依赖项目打包, 而是在生成的phar文件中放置依赖关系(通常是composer.json). 当phar文件执行, 它会自动注册一个类文件查找路径, 当发现缺少相关依赖时, 它会收集所有缺失依赖并提示用户确认下载相关依赖. 所以它更像是以Composer为基础的Linux发行版包管理系统.

关于Composer-phar, 请参考我的另一篇文章《在phar包中处理Composer依赖库:使用Composer-Phar》。 值得一提的是, Composer-Phar这一项目也是基于Symfony/Console开发的命令行程序, 具有一定参考价值. GitHub.

感谢你的阅读!本文系原创文章,出自 行间小筑 并遵循 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证),转载时请注明出处和本文链接:https://panlatent.com/archives/use-symfony-console

使用Bind9和NamedManager搭建DNS服务

在这篇文章里主要介绍如何使用搭建NamedManager来管理bind9。操作系统基于Ubuntu 14.04,需要安装PHP、Mysql与HTTP服务器。

Bind9

BIND (Berkeley Internet Name Domain)是Domain Name System (DNS) 协议的一个实现,提供了DNS主要功能的开放实现,包括域名服务器 (named)、DNS解析库函数 、DNS服务器运行调试所用的工具,是一款开放源码的DNS服务器软件,由美国加州大学Berkeley分校开发和维护。BIND是世界上使用最多最广泛的域名服务系统。

安装

其中bind9utils是bind9的命令行工具

NameManager

NameManager是一个管理DNS解析服务器的Web GUI。整个项目可以分为三个部分:

  • Web端用来配置DNS并保存到MySQL
  • 基于Cron的计划任务每分钟执行一次,将MySQL里面保存的记录刷新到Bind9的配置
  • 基于/etc/init.d的服务用来进行日志采集

安装

NameManager 在GitHub上的项目地址为: https://github.com/jethrocarr/namedmanager, 直接使用Git获得代码.

注意: 我的项目安装在/var/www下,全路径为/var/www/namedmanager。若是使用不同的安装路径,请在下面所有涉及到此路径的地方替换为你的安装路径

配置

配置文件

从样例配置文件创建配置文件

在/etc目录下创建namedmanager目录用来存放配置文件,并将配置文件软链接到该目录。NamedManager的服务进程和计划任务将会在此读取配置

修改配置文件

使用文本编辑器如vim编辑 /var/www/namedmanager/bind/include/config-settings.php

通信秘钥可以使用如下命令生成:

让Bind9包含NamedManager配置

创建NamedManager配置文件及目录

使用文本编辑器如vim编辑 /etc/bind/named.conf.local,添加

修改/etc/named.conf.options中的directory为/etc/bind/zones(即$config[“bind”][“zonefiledir”]的值)

如果想解析公网DNS, 在bind9的options中添加配置”allow-query-cache { any; };”

导入数据库

导入数据

请将[lasttime]替换成/var/www/namedmanager/sql目录下时间最晚的日期

创建Mysq用户并授权

配置HTTP服务

配置文件

创建配置文件

使用文本编辑器如vim编辑 /var/www/namedmanager/htdocs/includes/config-settings.php

这里的用户和密码是在上一步创建的, 可根据需要自行修改

Web服务器

创建Nginx或Apache等服务器的点站配置文件。

创建Cron计划任务

使用文本编辑器如vi编辑/etc/cron.d/namedmanager-bind, 将默认项目路径修改为你的项目路径。仅仅需要修改第一个计划任务

创建日志服务

使用文本编辑器如vi编辑/etc/init.d/namedmanager_logpush, 将默认项目路径修改为你的项目路径。
如果遇到”perl: warning: Please check that your locale settings”错误, 请按该教程修改http://blog.163.com/guoyong_1979/blog/static/502461620131016826127/
如果遇到”missing LSB tags and overrides”, 请将/etc/init.d/skeleton中### BEGIN INIT INFO 和 ### END INIT INFO 之间的内容复制到/etc/init.d/namedmanager_logpush
如果遇到”Can’t open /etc/rc.d/init.d/functions”, 在Ubuntu系统下在/lib/lsb/init-functions 可以ln -s或者修改文件
如果因为某些问题想重新执行 update-rc.d -f namedmanager_logpush defaults,请先执行 update-rc.d -f namedmanager_logpush remove

启动服务(仅在安装时需启动一次。本服务会随开机自动启动并且Cron计划任务会每天自动重启一次该服务)

最后

让我们使用浏览器管理你的DNS服务, 默认用户为setup,密码为setup123。

使用浏览器配置你的DNS

其他

注册被授权的DNS Server

使用搭建的DNS服务解析子域名

感谢你的阅读!本文系原创文章,出自 行间小筑 并遵循 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证),转载时请注明出处和本文链接:https://panlatent.com/archives/bind9-namedmanager

jQuery 遮罩引导插件:jQuery Guide

项目地址: https://github.com/panlatent/jquery-guide | 演示地址: Demo

介绍

jQuery Guide 是我实现的一个遮罩层用户操作引导插件。该插件的功能最初被我用在了一个操作比较复杂的活动页面上,用来指导用户如何进行操作,后提取成为 jQuery 插件。可用于网站改版的界面指引和功能介绍,配以适当且清晰的界面指引和提示, 可以让用户更快的了解和适应网站的功能。

使用方法

本项目源码可以在 GitHub上 获得,也可使用Bower包管理器下载:

引入 js 文件:

编辑动作:

例子:

$.guide() 是插件的注册函数,它需要一个 json 参数。json 参数目前只实现一个 actions 键功能. 「 actions 」是一个包含一系列连续引导的动作参数数组。

动作参数:
element: 被提示的元素,需要一个jQuery元素,如 $(‘#btn’)
content:提示内容(html)
offsetX:提示内容相对被提示元素的水平偏移位置
offsetY:提示内容相对被提示元素的垂直偏移位置
beforeFunc:动作执行之前执行函数[可选]
successFunc:动作执行之后执行函数[可选]

beforeFunc和successFunc回调函数都可以接受一个jQueryGuide类型实例的对象,即$.guide()创建的对象,通过这个参数可以在回调函数内控制动作的执行.

jQueryGuide 类

addAction(action) 添加一个动作
execAction() 执行当前动作
back() 返回上个动作并执行
next() 转到下个动作并执行
exit() 销毁遮罩层并退出引导

jQueryGuide 类内部使用一个属性来记录当前执行的动作的位置,back()/next() 的原理是改变位置并再次执行execAction()函数。

同时为了解决浏览器窗口大小改变引起的遮盖区域偏移的问题,$.guide() 会自动将 jQueryCuide::draw() 方法绑定到window对象的resize和scroll事件,重新绘制遮罩层。

感谢你的阅读!本文系原创文章,出自 行间小筑 并遵循 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证),转载时请注明出处和本文链接:https://panlatent.com/archives/jquery-guide