diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e3c849a3..0a3a428d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,7 @@ Pull requests are a great way to add new content to PHP The Right Way, as well as updating any browser issues or other style changes. Pretty much any sort of change is accepted if seen as constructive. -Adhering to the following this process is the best way to get your work +Adhering to the following process is the best way to get your work included in the project: 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, @@ -74,7 +74,7 @@ included in the project: 5. Commit your changes in logical chunks. Please adhere to these [git commit message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) or your content is unlikely be merged into the main project. Use Git's - [interactive rebase](https://help.github.com/articles/interactive-rebase) + [interactive rebase](https://help.github.com/articles/about-git--rebase/) feature to tidy up your commits before making them public. 6. Locally merge (or rebase) the upstream development branch into your topic branch: @@ -115,5 +115,5 @@ All content is completely free now, and always will be. 2. Use four (4) spaces to indent text; do not use tabs 3. Wrap all text to 120 characters 4. Code samples should adhere to PSR-1 or higher -5. Use [GitHub Flavored Markdown](http://github.github.com/github-flavored-markdown/) for all content +5. Use [GitHub Flavored Markdown](https://github.github.com/gfm/) for all content 6. Use language agnostic urls when referring to external websites such as the [php.net](http://php.net/urlhowto.php) manual diff --git a/README.md b/README.md index afee6fa21..d6aa6d6f6 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ * [한국어판](http://modernpug.github.io/php-the-right-way) * [日本語](http://ja.phptherightway.com) * [简体中文](https://laravel-china.github.io/php-the-right-way/) -* [繁體中文](http://laravel-taiwan.github.io/php-the-right-way) +* [繁體中文](https://laravel-taiwan.github.io/php-the-right-way) ### 翻译 diff --git a/_includes/welcome.md b/_includes/welcome.md index 6257fbaf0..cb2d18873 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -32,7 +32,7 @@ _PHP: The Right Way_ 被翻译为以下版本: * [한국어판](http://modernpug.github.io/php-the-right-way) * [日本語](http://ja.phptherightway.com) * [简体中文](https://laravel-china.github.io/php-the-right-way/) -* [繁體中文](http://laravel-taiwan.github.io/php-the-right-way) +* [繁體中文](https://laravel-taiwan.github.io/php-the-right-way) ## 书本 @@ -40,14 +40,8 @@ _PHP: The Right Way_ 被翻译为以下版本: ## 如何参与 {#how-to-contribute} -帮助我们让本网站作为 PHP 新手的最佳资源![在 GitHub 上贡献][2] - -## 推广 {#spread-the-word} - -_PHP: 您可以在网站上放置 PHP之道 的横幅来支持我们,让 PHP 的新人知道哪里可以获取到好的资料! - -[广告横幅][3] +帮助我们让本网站作为 PHP 新手的最佳资源![在 GitHub 上贡献 【English】][2] [【中文】][3] [1]: https://leanpub.com/phptherightway -[2]: https://github.com/summerblue/php-the-right-way/tree/gh-pages -[3]: /banners.html +[2]: https://github.com/codeguy/php-the-right-way/tree/gh-pages +[3]: https://github.com/laravel-china/php-the-right-way/tree/gh-pages diff --git a/_layouts/default.html b/_layouts/default.html index e43b7efd5..be898de72 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -5,12 +5,12 @@ {% if page.title %}{{ page.title }} - {% endif %} PHP 之道 | PHP The Right Way 中文版 - + - + diff --git a/_layouts/page.html b/_layouts/page.html index bb49295de..e2fce80a1 100644 --- a/_layouts/page.html +++ b/_layouts/page.html @@ -5,12 +5,12 @@ {% if page.title %}{{ page.title }} - {% endif %} PHP 之道 | PHP The Right Way 中文版 - + - + diff --git a/_posts/01-02-01-Use-the-Current-Stable-Version.md b/_posts/01-02-01-Use-the-Current-Stable-Version.md index 24da2366e..418970593 100644 --- a/_posts/01-02-01-Use-the-Current-Stable-Version.md +++ b/_posts/01-02-01-Use-the-Current-Stable-Version.md @@ -1,15 +1,15 @@ --- -title: 使用当前稳定版本 (7.1) +title: 使用当前稳定版本 (7.4) isChild: true anchor: use_the_current_stable_version --- -## 使用当前稳定版本 (7.1) {#use_the_current_stable_version_title} +## 使用当前稳定版本 (7.4) {#use_the_current_stable_version_title} -如果你刚开始学习 PHP,请使用最新的稳定版本 [PHP 7.1][php-release]。PHP 7.1 非常新,相较于 5.x 版本增加了强大的 [新特性](#language_highlights)。PHP 引擎大部分被重写,PHP 的运行速度已经远远超越过去。 +如果你刚开始学习 PHP,请使用最新的稳定版本 [PHP 7.4][php-release]。PHP 7.x 非常新,相较于 5.x 版本增加了强大的 [新特性](#language_highlights)。PHP 引擎大部分被重写,PHP 的运行速度已经远远超越过去。 -在很长的一段时间内,你会发现 5.x 还在广泛的被使用,目前最新的 5.x 版本是 5.6。对于当下,这并不是一个坏选项。然而,你应该尽快升级 - PHP 5.6 [将会在 2018 停止安全更新](http://php.net/supported-versions.php)。7.1 做了 [向下兼容][php71-bc] 处理,所以你的升级应该不会很难。. 如果你想查找一个函数及其用法,可以去官方手册 [php.net][php-docs] 中查找。 +在很长的一段时间内,你会发现 5.x 还在广泛的被使用,目前最新的 5.x 版本是 5.6。对于当下,这并不是一个坏选项。然而,你应该尽快升级 - PHP 5.6 [已经在 2018 停止安全更新](http://php.net/supported-versions.php)。7.4 做了 [向下兼容][php74-bc] 处理,所以你的升级应该不会很难。. 如果你想查找一个函数及其用法,可以去官方手册 [php.net][php-docs] 中查找。 [php-release]: http://php.net/downloads.php +[php74-bc]: http://php.net/manual/migration74.incompatible.php [php-docs]: http://php.net/manual/ -[php71-bc]: http://php.net/manual/migration71.incompatible.php diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index 512bc60c1..76d86a8a3 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -6,63 +6,67 @@ title: Mac 安裝 ## Mac 安装 {#mac_setup_title} -OS X 系统会预装 PHP, 只是一般情况下版本会比最新稳定版低一些。目前 -Mavericks 是 5.4.17、Yosemite 则是 5.5.9,El Capitan 是 5.5.29、Sierra 是 5.6.24, 但在 PHP 7.1 出来之后, 这些往往是不够的。 +macOS 系统会预装 PHP, 只是一般情况下版本会比最新稳定版低一些。 -以下介绍几种在 OS X 上安装 PHP 的方法。 +以下介绍几种在 macOS 上安装最新版本 PHP 的方法。 ### 通过 Homebrew 安装 PHP -[Homebrew] 是一个强大的 OS X 专用包管理器, 它可以帮助你轻松的安装 PHP 和各种扩展。 +[Homebrew] 是一个强大的 macOS 专用包管理器, 它可以帮助你轻松的安装 PHP 和各种扩展。 [Homebrew PHP] 是一个包含与 PHP 相关的 Formulae,能让你通过 homebrew 安装 PHP 的仓库。 -也就是说, 你可以通过 `brew install` 命令安装 `php53`、`php54`、`php55`、`php56`、`php70`或者 `php71`,并且通过修改 `PATH` 变量来切换各个版本。或者你也可以使用 [brew-php-switcher][brew-php-switcher] 来自动切换。 +也就是说, 你可以通过 `brew install` 命令安装 `php56`、`php70`、`php71`、`php72`、`php73` 或者 `php74`,使用以下命令安装最新版本: + + brew install php@7.4 + +您可以通过修改 `PATH` 变量在 Homebrew PHP 版本之间切换。或者你也可以使用 [brew-php-switcher][brew-php-switcher] 来自动切换。 -### Install PHP via Macports ### 通过 Macports 安装 PHP -[MacPorts] 是一个开源的,社区发起的项目,它的目的在于设计一个易于使用的系统,方便编译,安装以及升级 OS X 系统上的 command-line, X11 或者基于 Aqua 的开源软件。 +[MacPorts] 是一个开源的,社区发起的项目,它的目的在于设计一个易于使用的系统,方便编译,安装以及升级 macOS 系统上的 command-line, X11 或者基于 Aqua 的开源软件。 MacPorts 支持预编译的二进制文件,因此你不必每次都重新从源码压缩包编译,如果你的系统没有安装这些包,它会节省你很多时间。 -此时,你可以通过 `port install` 命名来安装 `php54`, `php55`, `php56`, `php70` 或者 `php71`,比如: +此时,你可以通过 `port install` 命名来安装 `php56`、`php70`、`php71`、`php72`、`php73` 或者 `php74`,比如: sudo port install php56 - sudo port install php71 + sudo port install php74 你也可以执行 `select` 命令来切换当前的 php 版本: - sudo port select --set php php71 + sudo port select --set php php74 ### 通过 phpbrew 安装 PHP [phpbrew] 是一个安装与管理多个 PHP 版本的工具。它在应用程序或者项目需要不同版本的 PHP 时非常有用,让你不再需要使用虚拟机来处理这些情况。 ### 通过 Liip's binary installer 安装 PHP -[php-osx.liip.ch] 是另一种流行的选择,它提供了从 5.3 到 7.1 版本的单行安装功能。 +[php-osx.liip.ch] 是另一种流行的选择,它提供了从 5.3 到 7.4 版本的单行安装功能。 它并不会覆盖Apple集成的PHP文件,而是将其安装在了一个独立的目录中(/usr/local/php5)。 ### 源码编译 另一个让你控制安装 PHP 版本的选择就是 [自行编译][mac-compile]。 -如果使用这种方法, 你必须先确认是否已经通过 「Apple's Mac Developer Center」 下载、安装 [Xcode][xcode-gcc-substitution] 或者 ["Command Line Tools for XCode"]。 +如果使用这种方法, 你必须先确认是否已经通过 Apple 的 Mac 开发人员中心下载、安装 [Xcode][xcode-gcc-substitution] 或者 ["XCode命令行工具(Command Line Tools for XCode)"][Command Line Tools for XCode]。 -### 集成包 (All-in-One Installers) +### 集成环境 (All-in-One Installers) -上面列出的解决方案主要是针对 PHP 本身, 并不包含:比如 Apache,Nginx 或者 SQL 服务器。 -集成包比如 [MAMP][mamp-downloads] 和 [XAMPP][xampp] 会安装这些软件并且将他们绑在一起,不过易于安装的背后也牺牲了一定的弹性。 +上面列出的解决方案主要是针对 PHP 本身, 并不包含:比如 [Apache],[Nginx] 或者 SQL Server 之类的东西。。 +集成环境比如 [MAMP][mamp-downloads] 和 [XAMPP][xampp] 会安装这些软件并且将他们绑在一起,不过易于安装的背后也牺牲了一定的弹性。 [Homebrew]: http://brew.sh/ [Homebrew PHP]: https://github.com/Homebrew/homebrew-php#installation +[brew-php-switcher]: https://github.com/philcook/brew-php-switcher [MacPorts]: https://www.macports.org/install.php [phpbrew]: https://github.com/phpbrew/phpbrew -[php-osx.liip.ch]: http://php-osx.liip.ch/ -[mac-compile]: http://php.net/install.macosx.compile +[php-osx.liip.ch]: https://php-osx.liip.ch/ +[mac-compile]: https://secure.php.net/install.macosx.compile [xcode-gcc-substitution]: https://github.com/kennethreitz/osx-gcc-installer -["Command Line Tools for XCode"]: https://developer.apple.com/downloads +[Command Line Tools for XCode]: https://developer.apple.com/downloads +[Apache]: https://httpd.apache.org/ +[Nginx]: https://www.nginx.com/ [mamp-downloads]: http://www.mamp.info/en/downloads/ [xampp]: http://www.apachefriends.org/en/xampp.html -[brew-php-switcher]: https://github.com/philcook/brew-php-switcher diff --git a/_posts/01-05-01-Windows-Setup.md b/_posts/01-05-01-Windows-Setup.md index 675166657..a99307923 100644 --- a/_posts/01-05-01-Windows-Setup.md +++ b/_posts/01-05-01-Windows-Setup.md @@ -8,21 +8,19 @@ title: Windows 安裝 你可以从 [windows.php.net/download][php-downloads] 下载二进制包。 解压后, 最好为你的 PHP 所在的根目录(php.exe 所在的文件夹)设置 [PATH][windows-path],这样就可以从命令行中直接执行 PHP。 -如果只是学习或者本地开发,可以直接使用 PHP 5.4+ 内置的 Web 服务器, 还能省去配置服务器的麻烦。如果你想要包含有网页服务器以及 MySql 的集成包,那么像是[Web Platform Installer][wpi], [XAMPP][xampp], [EasyPHP][easyphp] 和 [WAMP][wamp] 这类工具将会帮助你快速建立 Windows 开发环境。不过这些工具将会与线上环境有些许差别,如果你是在 Windows 下开发,而生产环境则部署至 Linux ,请小心。 +如果只是学习或者本地开发,可以直接使用 PHP 5.4+ 内置的 Web 服务器, 还能省去配置服务器的麻烦。如果你想要包含有网页服务器以及 MySql 的集成包,那么像是 [PhpStudy][phpstudy], [XAMPP][xampp] 和 [WAMP][wamp] 这类工具将会帮助你快速建立 Windows 开发环境。不过这些工具将会与线上环境有些许差别,如果你是在 Windows 下开发,而生产环境则部署至 Linux ,请小心。 如果你需要将生产环境部署在 Windows 上,那 IIS7 将会提供最稳定和最佳的性能。你可以使用 [phpmanager][phpmanager] (IIS7 的图形化插件) 让你简单的设置并管理 PHP。IIS7 也有内置的 FastCGI ,你只需要将 PHP 配置为它的处理器即可。更多详情请见[dedicated area on iis.net][php-iis]。 -一般情况下,使用不同环境开发,会导致你在上线代码时出现 Bug。如果你在 Window 下开发将会用于 Linux 下运行的代码,请应该考虑使用 [虚拟机](/#virtualization_title). +一般情况下,使用不同环境开发,会导致你在上线代码时出现 Bug。如果你在 Window 下开发将会用于 Linux(或任何非Windows) 下运行的代码,请应该考虑使用 [虚拟机](/#virtualization_title). 这里推荐 Chris Tankersley 的一篇关于 Window 下工具使用的文章 - [Windows 下的 PHP 开发][windows-tools]. -[easyphp]: http://www.easyphp.org/ -[phpmanager]: http://phpmanager.codeplex.com/ -[openserver]: http://open-server.ru/ -[wamp]: http://www.wampserver.com/en/ [php-downloads]: http://windows.php.net/download/ -[php-iis]: http://php.iis.net/ [windows-path]: http://www.windows-commandline.com/set-path-command-line/ -[windows-tools]: http://ctankersley.com/2016/11/13/developing-on-windows-2016/ -[wpi]: https://www.microsoft.com/web/downloads/platform.aspx +[phpstudy]: https://www.xp.cn/download.html [xampp]: http://www.apachefriends.org/en/xampp.html +[wamp]: http://www.wampserver.com/en/ +[phpmanager]: http://phpmanager.codeplex.com/ +[php-iis]: http://php.iis.net/ +[windows-tools]: http://ctankersley.com/2016/11/13/developing-on-windows-2016/ diff --git a/_posts/01-06-01-Common-Directory-structure.md b/_posts/01-06-01-Common-Directory-structure.md new file mode 100644 index 000000000..5689b1263 --- /dev/null +++ b/_posts/01-06-01-Common-Directory-structure.md @@ -0,0 +1,19 @@ +--- +isChild: true +anchor: common_directory_structure +title: 常见目录结构 +--- + +## 常见目录结构 {#common_directory_structure} + +对于那些刚开始为web编写程序的人来说,一个常见的问题是:“我应该把我的文件放在哪里?” 多年来,这个答案一直是“DocumentRoot 指向的目录”。虽然这个答案还不完整,但这是一个很好的开始。 + +出于安全原因,配置文件不应该被人访问到; 因此,公共脚本保存在公共目录中,私有配置和数据保存在该目录之外。 + +对于 每个团队、CMS或框架,这些实体都有目录结构标准。但是,如果个人开发一个项目,那么选择使用哪种文件结构都是一件令人烦恼的事。 + +[Paul M. Jones] 对 github上成千上万的 PHP 项目中进行了研究。根据研究结果,他编写了一套标准文件和目录结构的标准,即 [Standard PHP Package Skeleton]。在这个目录结构中,`DocumentRoot` 应该指向 `public/`,单元测试应该在 `tests/`目录中,而 `composer` 安装的第三方包应该在 `vender/` 目录。对于其他文件和目录,遵循[标准的PHP包和框架目录标准][Standard PHP Package Skeleton]对项目的发展是非常有意义的。 + +[Paul M. Jones]: http://paul-m-jones.com/ +[Standard PHP Package Skeleton]: https://github.com/php-pds/skeleton +[Composer]: /#composer_and_packagist \ No newline at end of file diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 3768f4a52..e68e63d03 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -7,13 +7,12 @@ title: 代码风格指南 PHP 社区百花齐放,拥有大量的函数库、框架和组件。PHP 开发者通常会在自己的项目中使用若干个外部库,因此 PHP 代码遵循(尽可能接近)同一个代码风格就非常重要,这让开发者可以轻松地将多个代码库整合到自己的项目中。 -[PHP标准组][fig] 提出并发布了一系列的风格建议。其中有部分是关于代码风格的,即 [PSR-0][psr0], [PSR-1][psr1], [PSR-2][psr2] 和 [PSR-4][psr4]。这些推荐只是一些被其他项目所遵循的规则,如 Drupal, Zend, Symfony, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium 等。你可以把这些规则用在自己的项目中,或者继续使用自己的风格。 +[PHP标准组织][fig] 提出并发布了一系列的风格建议。其中有部分是关于代码风格的,即 [PSR-1][psr1], [PSR-12][psr12] 和 [PSR-4][psr4]。这些推荐只是一些被其他项目所遵循的规则,如 Drupal, Zend, Symfony, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium 等。你可以把这些规则用在自己的项目中,或者继续使用自己的风格。 通常情况下,你应该遵循一个已知的标准来编写 PHP 代码。可能是 PSR 的组合或者是 PEAR 或 Zend 编码准则中的一个。这代表其他开发者能够方便的阅读和使用你的代码,并且使用这些组件的应用程序可以和其他第三方的组件保持一致。 -* [阅读 PSR-0][psr0] * [阅读 PSR-1][psr1] -* [阅读 PSR-2][psr2] +* [阅读 PSR-12][psr12] * [阅读 PSR-4][psr4] * [阅读 PEAR 编码准则][pear-cs] * [阅读 Symfony 编码准则][symfony-cs] @@ -23,33 +22,37 @@ PHP 社区百花齐放,拥有大量的函数库、框架和组件。PHP 开发 你可以通过任意以下两个工具来自动修正你的程序语法,让它符合标准: - 一个是 [PHP Coding Standards Fixer][phpcsfixer],它具有良好的测试。 -- 另一个是随 PHP_CodeSniffer 安装的 [PHP Code 美化修整器][phpcbf]。 +- 另一个是随 PHP_CodeSniffer 安装的 [PHP代码美化修整器][phpcbf]。 你也可以手动运行 phpcs 命令: - phpcs -sw --standard=PSR2 file.php + phpcs -sw --standard=PSR1 file.php 它会显示出相应的错误以及如何修正的方法。同时,这条命令你也可以用在 git hook 中,如果你的分支代码不符合选择的代码标准则无法提交。 -如果你已经安装了 PHP_CodeSniffer,你将可以使用 -[PHP Code 美化修整器][phpcbf] 来格式化代码: +如果你已经安装了 PHP_CodeSniffer,你将可以使用 [PHP代码美化修整器][phpcbf] 来格式化代码: - phpcbf -w --standard=PSR2 file.php + phpcbf -w --standard=PSR1 file.php 另一个选项是使用 [PHP 编码标准修复器][phpcsfixer],他可以让你预览编码不合格的部分: - php-cs-fixer fix -v --level=psr2 file.php + php-cs-fixer fix -v --level=psr1 file.php 所有的变量名称以及代码结构建议用英文编写。注释可以使用任何语言,只要让现在以及未来的小伙伴能够容易阅读理解即可。 -[fig]: https://psr.phphub.org/ -[psr0]: http://www.php-fig.org/psr/psr-0/ -[psr1]: https://laravel-china.org/topics/2078 -[psr2]: https://laravel-china.org/topics/2079 -[psr4]: https://laravel-china.org/topics/2081 -[pear-cs]: http://pear.php.net/manual/en/standards.php -[symfony-cs]: http://symfony.com/doc/current/contributing/code/standards.html -[phpcs]: http://pear.php.net/package/PHP_CodeSniffer/ +最后,补充一个简洁PHP的资源 [Clean Code PHP][cleancode]. + + +[fig]: https://www.php-fig.org/ +[psr1]: https://www.php-fig.org/psr/psr-1/ +[psr12]: https://www.php-fig.org/psr/psr-12/ +[psr4]: https://www.php-fig.org/psr/psr-4/ +[pear-cs]: https://pear.php.net/manual/en/standards.php +[symfony-cs]: https://symfony.com/doc/current/contributing/code/standards.html +[phpcs]: https://pear.php.net/package/PHP_CodeSniffer/ [phpcbf]: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Fixing-Errors-Automatically [st-cs]: https://github.com/benmatselby/sublime-phpcs -[phpcsfixer]: http://cs.sensiolabs.org/ +[phpcsfixer]: https://cs.sensiolabs.org/ +[cleancode]: https://github.com/jupeter/clean-code-php + + diff --git a/_posts/03-02-01-Programming-Paradigms.md b/_posts/03-02-01-Programming-Paradigms.md index b4eca1673..c6a7d674f 100644 --- a/_posts/03-02-01-Programming-Paradigms.md +++ b/_posts/03-02-01-Programming-Paradigms.md @@ -40,14 +40,15 @@ PHP 通过反射 API 和魔术方法,可以实现多种方式的元编程。 * [阅读反射][reflection] * [阅读重载][overloading] -[oop]: http://php.net/language.oop5 -[traits]: http://php.net/language.oop5.traits -[anonymous-functions]: http://php.net/functions.anonymous -[closure-class]: http://php.net/class.closure +[oop]: https://secure.php.net/language.oop5 +[traits]: https://secure.php.net/language.oop5.traits +[anonymous-functions]: https://secure.php.net/functions.anonymous +[closure-class]: https://secure.php.net/class.closure [closures-rfc]: https://wiki.php.net/rfc/closures -[callables]: http://php.net/language.types.callable -[call-user-func-array]: http://php.net/function.call-user-func-array -[magic-methods]: http://php.net/language.oop5.magic -[reflection]: http://php.net/intro.reflection -[overloading]: http://php.net/language.oop5.overloading +[callables]: https://secure.php.net/language.types.callable +[call-user-func-array]: https://secure.php.net/function.call-user-func-array +[magic-methods]: https://secure.php.net/language.oop5.magic +[reflection]: https://secure.php.net/intro.reflection +[overloading]: https://secure.php.net/language.oop5.overloading + diff --git a/_posts/03-03-01-Namespaces.md b/_posts/03-03-01-Namespaces.md index 19d73cbe1..fa2693276 100644 --- a/_posts/03-03-01-Namespaces.md +++ b/_posts/03-03-01-Namespaces.md @@ -23,6 +23,7 @@ _命名空间_ 解决了这个问题。如 PHP 手册里所描述,命名空间 * [阅读 PSR-0][psr0] * [阅读 PSR-4][psr4] -[namespaces]: http://php.net/language.namespaces -[psr0]: http://www.php-fig.org/psr/psr-0/ -[psr4]: http://www.php-fig.org/psr/psr-4/ +[namespaces]: https://secure.php.net/language.namespaces +[psr0]: https://www.php-fig.org/psr/psr-0/ +[psr4]: https://www.php-fig.org/psr/psr-4/ + diff --git a/_posts/03-04-01-Standard-PHP-Library.md b/_posts/03-04-01-Standard-PHP-Library.md index a179469cf..4e6d123f9 100644 --- a/_posts/03-04-01-Standard-PHP-Library.md +++ b/_posts/03-04-01-Standard-PHP-Library.md @@ -11,5 +11,6 @@ PHP 标准库 (Standard PHP Library 简写为 SPL) 随着 PHP 一起发布,提 * [阅读 SPL][spl] * [Lynda.com 上的 SPL 视频教程(付费)][spllynda] -[spl]: http://php.net/book.spl -[spllynda]: http://www.lynda.com/PHP-tutorials/Up-Running-Standard-PHP-Library/175038-2.html +[spl]: https://secure.php.net/book.spl +[spllynda]: https://www.lynda.com/PHP-tutorials/Up-Running-Standard-PHP-Library/175038-2.html + diff --git a/_posts/03-05-01-Command-Line-Interface.md b/_posts/03-05-01-Command-Line-Interface.md index b5e8c6062..d7872ddaf 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -25,7 +25,7 @@ CLI PHP 编程非常强大,可以直接调用你自己的程序代码而无需 {% highlight php %} .\n"; exit(1); } $name = $argv[1]; @@ -41,18 +41,16 @@ PHP 会在脚本运行时根据参数设置两个特殊的变量,[`$argc`][arg {% highlight console %} > php hello.php -Usage: php hello.php [name] +Usage: php hello.php > php hello.php world Hello, world {% endhighlight %} * [学习如何在命令行运行 PHP][php-cli] - * [学习如何在 Windows 环境下运行 PHP 命令行程序][php-cli-windows] - -[phpinfo]: http://php.net/function.phpinfo -[cli-options]: http://php.net/features.commandline.options -[argc]: http://php.net/reserved.variables.argc -[argv]: http://php.net/reserved.variables.argv -[exit-codes]: http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits -[php-cli]: http://php.net/features.commandline -[php-cli-windows]: http://php.net/install.windows.commandline + +[phpinfo]: https://secure.php.net/function.phpinfo +[cli-options]: https://secure.php.net/features.commandline.options +[argc]: https://secure.php.net/reserved.variables.argc +[argv]: https://secure.php.net/reserved.variables.argv +[exit-codes]: https://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits +[php-cli]: https://secure.php.net/features.commandline.options diff --git a/_posts/03-06-01-XDebug.md b/_posts/03-06-01-XDebug.md index 91ca63846..02db0ea8a 100644 --- a/_posts/03-06-01-XDebug.md +++ b/_posts/03-06-01-XDebug.md @@ -30,6 +30,7 @@ php_value xdebug.remote_port=9000 * [学习更多 Xdebug][xdebug-docs] * [学习更多 MacGDBp][macgdbp-install] -[xdebug-install]: http://xdebug.org/docs/install -[xdebug-docs]: http://xdebug.org/docs/ -[macgdbp-install]: http://www.bluestatic.org/software/macgdbp/ +[xdebug-install]: https://xdebug.org/docs/install +[xdebug-docs]: https://xdebug.org/docs/ +[macgdbp-install]: https://www.bluestatic.org/software/macgdbp/ + diff --git a/_posts/04-02-01-Composer-and-Packagist.md b/_posts/04-02-01-Composer-and-Packagist.md index 5e9568a8f..c9eac1564 100644 --- a/_posts/04-02-01-Composer-and-Packagist.md +++ b/_posts/04-02-01-Composer-and-Packagist.md @@ -6,18 +6,23 @@ anchor: composer_and_packagist ## Composer 与 Packagist {#composer_and_packagist_title} -Composer 是一个 **杰出** 的依赖管理器。在 `composer.json` 文件中列出你项目所需的依赖包,加上一点简单的命令,Composer 将会自动帮你下载并设置你的项目依赖。Composer 有点类似于 Node.js 世界里的 NPM,或者 Ruby 世界里的 Bundler。 +对于 PHP 来说,Composer 是一个推荐的依赖管理器。在 `composer.json` 文件中列出你项目所需的依赖包,加上一点简单的命令,Composer 将会自动帮你下载并设置你的项目依赖。Composer 有点类似于 Node.js 世界里的 NPM,或者 Ruby 世界里的 Bundler。 -现在已经有许多 PHP 第三方包已兼容 Composer,随时可以在你的项目中使用。这些「packages(包)」都已列在 [Packagist],这是一个官方的 Composer 兼容包仓库。 +现在有非常多的 PHP 第三方包已兼容 Composer,随时可以在你的项目中使用。这些「packages(包)」都已列在 [Packagist],这是一个官方的 Composer 兼容包仓库。 -> 为了提高国内 Composer 的使用体验,Laravel China 社区维护了 [Composer 中文镜像 /Packagist 中国全量镜像](https://laravel-china.org/composer) ,此镜像使用了又拍云的 CDN 加速,将会极大加速 Composer 依赖的下载速度。 +> 为了提高国内 Composer 的使用体验,可以使用 [Composer 中文镜像 /Packagist 中国全量镜像](https://pkg.phpcomposer.com/) ,将会极大加速 Composer 依赖的下载速度。 ### 如何安装 Composer +The safest way to download composer is by [following the official instructions](https://getcomposer.org/download/). +This will verify the installer is not corrupt or tampered with. +The installer installs a `composer.phar` binary in your _current working directory_. + + 最安全的下载方法就是使用 [官方的教程](https://getcomposer.org/download/)。 此方法会验证安装器是否安全,是否被修改。 -安装器安装 Composer 的应用范围为 *本地*,也就是在你当前项目文件夹。 +安装器会下载一个 `composer.phar` 的文件在你运行安装器的目录,也就是在你当前执行命令的文件夹。 我们推荐你 *全局* 安装,即把可执行文件复制到 `/usr/local/bin` 路径中: @@ -33,39 +38,12 @@ mv composer.phar /usr/local/bin/composer 对于Windows 的用户而言最简单的获取及执行方法就是使用 [ComposerSetup] 安装程序,它会执行一个全局安装并设置你的 `$PATH`,所以你在任意目录下在命令行中使用 `composer`。 -### 如何手动安装 Composer - -手动安装 Composer 是一个高端的技术。仅管如此还是有许多开发者有各种原因喜欢使用这种交互式的应用程序安装 Composer。在安装前请先确认你的 PHP 安装项目如下: - -- 正在使用一个满足条件的 PHP 版本 -- `.phar` 文件可以正确的被执行 -- 相关的目录有足够的权限 -- 相关有问题的扩展没有被载入 -- 相关的 `php.ini` 设置已完成 - -由于手动安装没有执行这些检查,你必须自已衡量决定是否值得做这些事,以下是如何手动安装 Composer : - -{% highlight console %} -curl -s https://getcomposer.org/composer.phar -o $HOME/local/bin/composer -chmod +x $HOME/local/bin/composer -{% endhighlight %} - -路径 `$HOME/local/bin` (或是你选择的路径) 应该在你的 `$PATH` 环境变量中。这将会影响 `composer` 这个命令是否可用. - -当你遇到文档指出执行 Composer 的命令是 `php composer.phar install`时,你可以使用下面命令替代: - -{% highlight console %} -composer install -{% endhighlight %} - -本章节会假设你已经安装了全局的 Composer。 - ### 如何设置及安装依赖 Composer 会通过一个 `composer.json` 文件持续的追踪你的项目依赖。 如果你喜欢,你可以手动管理这个文件,或是使用 Composer 自己管理。`composer require` 这个指令会增加一个项目依赖,如果你还没有 `composer.json` 文件, 将会创建一个。这里有个例子为你的项目加入 [Twig] 依赖。 {% highlight console %} -composer require twig/twig:~1.8 +composer require twig/twig:~2.0 {% endhighlight %} 另外 `composer init` 命令将会引导你创建一个完整的 `composer.json` 文件到你的项目之中。无论你使用哪种方式,一旦你创建了 `composer.json` 文件,你可以告诉 Composer 去下载及安装你的依赖到 `vendor/` 目录中。这命令也适用于你已经下载并已经提供了一个 `composer.json` 的项目: @@ -91,7 +69,7 @@ Composer 会建立一个 `composer.lock` 文件,在你第一次执行 `php com ### 更新通知 -要接收关于新版本的更新通知。你可以注册 [VersionEye],这个 web 服务可以监控你的 Github 及 BitBucket 帐号中的 `composer.json` 文件,并且当包有新更新时会发送邮件给你。 +要接收关于新版本的更新通知。你可以注册 [libraries.io],这个 web 服务可以监控你的 Github 及 BitBucket 帐号中的 `composer.json` 文件,并且当包有新更新时会发送邮件给你。 ### 检查你的依赖安全问题 @@ -109,9 +87,9 @@ composer global require phpunit/phpunit * [其他学习 Composer 相关资源][Learn about Composer] -[Packagist]: http://packagist.org/ -[Twig]: http://twig.sensiolabs.org -[VersionEye]: https://www.versioneye.com/ -[Security Advisories Checker]: https://security.sensiolabs.org/ -[Learn about Composer]: http://getcomposer.org/doc/00-intro.md +[Packagist]: https://packagist.org/ +[Twig]: https://twig.symfony.com/ +[libraries.io]: https://libraries.io/ +[Security Advisories Checker]: https://security.symfony.com/ +[Learn about Composer]: https://getcomposer.org/doc/00-intro.md [ComposerSetup]: https://getcomposer.org/Composer-Setup.exe diff --git a/_posts/04-03-01-PEAR.md b/_posts/04-03-01-PEAR.md index d3bc51f9f..aee19d5b6 100644 --- a/_posts/04-03-01-PEAR.md +++ b/_posts/04-03-01-PEAR.md @@ -41,7 +41,7 @@ pear install foo "repositories": [ { "type": "pear", - "url": "http://pear2.php.net" + "url": "https://pear2.php.net" } ], "require": { @@ -70,9 +70,9 @@ $request = new pear2\HTTP\Request(); * [学习更多 PEAR 和 Composer 的使用][6] -[1]: http://pear.php.net/ -[2]: http://pear.php.net/manual/en/installation.getting.php -[3]: http://pear.php.net/packages.php -[4]: http://pear.php.net/manual/en/guide.users.commandline.channels.php +[1]: https://pear.php.net/ +[2]: https://pear.php.net/manual/installation.getting.php +[3]: https://pear.php.net/packages.php +[4]: https://pear.php.net/manual/guide.users.commandline.channels.php [5]: /#composer_and_packagist [6]: http://getcomposer.org/doc/05-repositories.md#pear diff --git a/_posts/05-02-01-The-Basics.md b/_posts/05-02-01-The-Basics.md index 7cb9dc87b..91257718a 100644 --- a/_posts/05-02-01-The-Basics.md +++ b/_posts/05-02-01-The-Basics.md @@ -8,4 +8,4 @@ title: 基础知识 PHP 是一门庞大的语言,各个水平层次的开发者都可以利用它进行迅捷高效的开发。然而在对语言逐渐深入的学习过程中,我们往往会因为走捷径和/或不良习惯而忘记(或忽视掉)基础的知识。为了帮助彻底解决这个问题,这一章的目的就是提醒开发人员注意有关 PHP 的基础编程实践。 -* 学习更多[基础知识](/php-the-right-way/pages/The-Basics.html) \ No newline at end of file +* 学习更多[基础知识](/pages/The-Basics.html) \ No newline at end of file diff --git a/_posts/05-03-01-Date-and-Time.md b/_posts/05-03-01-Date-and-Time.md index 3858ad7a2..7a20459f9 100644 --- a/_posts/05-03-01-Date-and-Time.md +++ b/_posts/05-03-01-Date-and-Time.md @@ -53,10 +53,10 @@ foreach ($periodIterator as $date) { } {% endhighlight %} -一个有名的 API 扩展是 [Carbon](http://carbon.nesbot.com)。Carbon 不仅继承了所有 DateTime 类提供的功能,还提供了更多的人性化功能,例如自然语言时间处理、国际化支持、对象之间执行增减算术。 +一个有名的 API 扩展是 [Carbon](https://carbon.nesbot.com)。Carbon 不仅继承了所有 DateTime 类提供的功能,还提供了更多的人性化功能,例如自然语言时间处理、国际化支持、对象之间执行增减算术。 * [阅读 DateTime][datetime] * [阅读日期格式][dateformat] (支持的日期字符串格式) -[datetime]: http://php.net/book.datetime -[dateformat]: http://php.net/function.date +[datetime]: https://secure.php.net/book.datetime +[dateformat]: https://secure.php.net/function.date diff --git a/_posts/05-04-01-Design-Patterns.md b/_posts/05-04-01-Design-Patterns.md index fa566d4c6..117ba0592 100644 --- a/_posts/05-04-01-Design-Patterns.md +++ b/_posts/05-04-01-Design-Patterns.md @@ -10,4 +10,4 @@ title: 设计模式 当你使用框架进行开发时,绝大部分的上层代码以及项目结构都会基于所使用的框架,因此很多关于设计模式的决定已经由框架帮你做好了。当然,你还是可以挑选你最喜欢的模式并在你的代码中进行应用。但如果你并没有使用框架的话,你就需要自己去寻找适合你的应用的最佳模式了。 -* 学习更多[设计模式](/php-the-right-way/pages/Design-Patterns.html) +学习更多设计模式: diff --git a/_posts/05-05-01-PHP-and-UTF8.md b/_posts/05-05-01-PHP-and-UTF8.md index e194320ba..978d39e4f 100644 --- a/_posts/05-05-01-PHP-and-UTF8.md +++ b/_posts/05-05-01-PHP-and-UTF8.md @@ -28,7 +28,7 @@ _本章是由 [Alex Cabal](https://alexcabal.com/) 最初撰写在 [PHP Best Pra 最后,如果你所编写的是分布式的应用程序并且不能确定 `mbstring` 扩展一定开启的话,可以考虑使用 [patchwork/utf8] Composer 包。它会在 `mbstring` 可用时自动使用,否则自动切换回非 UTF-8 函数。 -[Multibyte String Extension]: http://php.net/book.mbstring +[Multibyte String Extension]: https://secure.php.net/book.mbstring [patchwork/utf8]: https://packagist.org/packages/patchwork/utf8 ### 数据库层面的 UTF-8 @@ -43,26 +43,38 @@ _本章是由 [Alex Cabal](https://alexcabal.com/) 最初撰写在 [PHP Best Pra 使用 `mb_http_output()` 函数来确保 PHP 向浏览器输出 UTF-8 格式的字符串。 -随后浏览器需要接收 HTTP 应答来指定页面是由 UTF-8 进行编码的。以前这一步是通过在页面 `` 标签下包含[字符集 `` 标签](http://htmlpurifier.org/docs/enduser-utf8.html)实现的,这是一种可行的方式。但更好的做法是在 `Content-Type` 响应头中进行设置,因为这样做的速度会[更快](https://developers.google.com/speed/docs/best-practices/rendering#SpecifyCharsetEarly)。 +然后,通过 HTTP 响应告知浏览器该页面是由 UTF-8 进行编码的。如今,常见的是在 HTTP 响应标头 `Content-Type` 中设置字符集,因为这样做的速度会[更快](https://developers.google.com/speed/docs/best-practices/rendering#SpecifyCharsetEarly)。如下所示: {% highlight php %} ` 标签下包含[字符集 `` 标签](https://htmlpurifier.org/docs/enduser-utf8.html)实现的,这是一种可行的方式。 + +{% highlight php %} + false ) ); - -// Store our transformed string as UTF-8 in our database -// Your DB and tables are in the utf8mb4 character set and collation, right? -$handle = $link->prepare('insert into ElvishSentences (Id, Body) values (?, ?)'); -$handle->bindValue(1, 1, PDO::PARAM_INT); -$handle->bindValue(2, $string); + +// 将转换后的字符串存储为数据库中的UTF-8 +// 您的数据库和表位于utf8mb4字符集和排序规则中,对吗? +$handle = $link->prepare('insert into ElvishSentences (Id, Body, Priority) values (default, :body, :priority)'); +$handle->bindParam(':body', $string, PDO::PARAM_STR); +$priority = 45; +$handle->bindParam(':priority', $priority, PDO::PARAM_INT); // 明确告诉pdo期望一个int $handle->execute(); - -// Retrieve the string we just stored to prove it was stored correctly -$handle = $link->prepare('select * from ElvishSentences where Id = ?'); -$handle->bindValue(1, 1, PDO::PARAM_INT); + +// 检索我们刚刚存储的字符串以证明它已正确存储 +$handle = $link->prepare('select * from ElvishSentences where Id = :id'); +$id = 7; +$handle->bindParam(':id', $id, PDO::PARAM_INT); $handle->execute(); - -// Store the result into an object that we'll output later in our HTML + +// 将结果存储到我们稍后将在HTML中输出的对象中 +// 该对象不会杀死您的内存,因为它会及时获取到数据 +// This object won't kill your memory because it fetches the data Just-In-Time to $result = $handle->fetchAll(\PDO::FETCH_OBJ); -header('Content-Type: text/html; charset=UTF-8'); +// 包装器示例,可让您将数据转义为html +function escape_to_html($dirty){ + echo htmlspecialchars($dirty, ENT_QUOTES, 'UTF-8'); +} + +header('Content-Type: text/html; charset=UTF-8'); // 如果您的 default_charset 已设置为 utf-8,则不需要再次设置 ?> @@ -98,7 +119,7 @@ header('Content-Type: text/html; charset=UTF-8'); Body); // This should correctly output our transformed UTF-8 string to the browser + escape_to_html($row->Body); // 这应该正确地将我们转换后的UTF-8字符串输出到浏览器 } ?> @@ -107,23 +128,23 @@ header('Content-Type: text/html; charset=UTF-8'); ### Further reading -* [PHP 手册:字符串运算符](http://php.net/language.operators.string) -* [PHP 手册:字符串函数](http://php.net/ref.strings) - * [`strpos()`](http://php.net/function.strpos) - * [`strlen()`](http://php.net/function.strlen) - * [`substr()`](http://php.net/function.substr) -* [PHP 手册:多字节字符串函数](http://php.net/ref.mbstring) - * [`mb_strpos()`](http://php.net/function.mb-strpos) - * [`mb_strlen()`](http://php.net/function.mb-strlen) - * [`mb_substr()`](http://php.net/function.mb-substr) - * [`mb_internal_encoding()`](http://php.net/function.mb-internal-encoding) - * [`mb_http_output()`](http://php.net/function.mb-http-output) - * [`htmlentities()`](http://php.net/function.htmlentities) - * [`htmlspecialchars()`](http://php.net/function.htmlspecialchars) -* [PHP UTF-8 Cheatsheet](http://blog.loftdigital.com/blog/php-utf-8-cheatsheet) -* [Handling UTF-8 with PHP](http://www.phpwact.org/php/i18n/utf-8) -* [Stack Overflow: What factors make PHP Unicode-incompatible?](http://stackoverflow.com/questions/571694/what-factors-make-php-unicode-incompatible) -* [Stack Overflow: Best practices in PHP and MySQL with international strings](http://stackoverflow.com/questions/140728/best-practices-in-php-and-mysql-with-international-strings) -* [How to support full Unicode in MySQL databases](http://mathiasbynens.be/notes/mysql-utf8mb4) -* [Bringing Unicode to PHP with Portable UTF-8](http://www.sitepoint.com/bringing-unicode-to-php-with-portable-utf8/) -* [Stack Overflow: DOMDocument loadHTML does not encode UTF-8 correctly](http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8-correctly) +* [PHP 手册:字符串运算符](https://php.net/language.operators.string) +* [PHP 手册:字符串函数](https://php.net/ref.strings) + * [`strpos()`](https://php.net/function.strpos) + * [`strlen()`](https://php.net/function.strlen) + * [`substr()`](https://php.net/function.substr) +* [PHP 手册:多字节字符串函数](https://php.net/ref.mbstring) + * [`mb_strpos()`](https://php.net/function.mb-strpos) + * [`mb_strlen()`](https://php.net/function.mb-strlen) + * [`mb_substr()`](https://php.net/function.mb-substr) + * [`mb_internal_encoding()`](https://php.net/function.mb-internal-encoding) + * [`mb_http_output()`](https://php.net/function.mb-http-output) + * [`htmlentities()`](https://php.net/function.htmlentities) + * [`htmlspecialchars()`](https://php.net/function.htmlspecialchars) +* [PHP UTF-8 Cheatsheet](https://blog.loftdigital.com/blog/php-utf-8-cheatsheet) +* [Handling UTF-8 with PHP](https://www.phpwact.org/php/i18n/utf-8) +* [Stack Overflow: What factors make PHP Unicode-incompatible?](https://stackoverflow.com/questions/571694/what-factors-make-php-unicode-incompatible) +* [Stack Overflow: Best practices in PHP and MySQL with international strings](https://stackoverflow.com/questions/140728/best-practices-in-php-and-mysql-with-international-strings) +* [How to support full Unicode in MySQL databases](https://mathiasbynens.be/notes/mysql-utf8mb4) +* [Bringing Unicode to PHP with Portable UTF-8](https://www.sitepoint.com/bringing-unicode-to-php-with-portable-utf8/) +* [Stack Overflow: DOMDocument loadHTML does not encode UTF-8 correctly](https://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8-correctly) diff --git a/_posts/05-06-01-Internationalization-and-Localization.md b/_posts/05-06-01-Internationalization-and-Localization.md index 84cf46349..499723d16 100644 --- a/_posts/05-06-01-Internationalization-and-Localization.md +++ b/_posts/05-06-01-Internationalization-and-Localization.md @@ -19,21 +19,23 @@ _前置声明:i18n 和 l10n 是使用数字简略拼写方式来实现缩写 最简便的方式是使用数组键值对应的方式如 `

`,不过在比较正经的项目中,不建议这么做。因为会随着项目代码慢慢变多,维护的难度将会增加,尤其会阻碍后续本地化实施。 The most classic way and often taken as reference for i18n and l10n is a [Unix tool called `gettext`][gettext]. It dates -back to 1995 and is still a complete implementation for translating software. It is pretty easy to get running, while -it still sports powerful supporting tools. It's about Gettext we will be talking here. Also, to help you not get messy +back to 1995 and is still a complete implementation for translating software. It is easy enough to get running, while +still sporting powerful supporting tools. It is about Gettext we will be talking here. Also, to help you not get messy over the command-line, we will be presenting a great GUI application that can be used to easily update your l10n source -files. ### Other tools There are common libraries used that support Gettext and other implementations of i18n. Some of them may seem easier to -install or sport additional features or i18n file formats. In this document, we focus on the tools provided with the +install or sport additional features or i18n file formats. In this document, we focus on the tools provided with the PHP core, but here we list others for completion: +- [aura/intl][aura-intl]: Provides internationalization (I18N) tools, specifically package-oriented per-locale message +translation. It uses array formats for message. Does not provide a message extractor, but does provide advanced +message formatting via the `intl` extension (including pluralized messages). - [oscarotero/Gettext][oscarotero]: Gettext support with an OO interface; includes improved helper functions, powerful extractors for several file formats (some of them not supported natively by the `gettext` command), and can also export -to other formats besides `.mo/.po` files. Can be useful if you need to integrate your translation files into other parts -of the system, like a JavaScript interface. +to other formats besides `.mo/.po` files. Can be useful if you need to integrate your translation files into other +parts of the system, like a JavaScript interface. - [symfony/translation][symfony]: supports a lot of different formats, but recommends using verbose XLIFF's. Doesn't include helper functions nor a built-in extractor, but supports placeholders using `strtr()` internally. - [zend/i18n][zend]: supports array and INI files, or Gettext formats. Implements a caching layer to save you from @@ -41,6 +43,7 @@ reading the filesystem every time. It also includes view helpers, and locale-awa However, it has no message extractor. Other frameworks also include i18n modules, but those are not available outside of their codebases: + - [Laravel] supports basic array files, has no automatic extractor but includes a `@lang` helper for template files. - [Yii] supports array, Gettext, and database-based translation, and includes a messages extractor. It is backed by the [`Intl`][intl] extension, available since PHP 5.3, and based on the [ICU project]; this enables Yii to run powerful @@ -57,7 +60,7 @@ After installed, enable it by adding `extension=gettext.so` (Linux/Unix) or `ext your `php.ini`. Here we will also be using [Poedit] to create translation files. You will probably find it in your system's package -manager; it's available for Unix, Mac, and Windows, and can be [downloaded for free on their website][poedit_download] +manager; it is available for Unix, Mac, and Windows, and can be [downloaded for free on their website][poedit_download] as well. ### Structure @@ -65,31 +68,31 @@ as well. #### Types of files There are three files you usually deal with while working with gettext. The main ones are PO (Portable Object) and MO (Machine Object) files, the first being a list of readable "translated objects" and the second, the corresponding -binary to be interpreted by gettext when doing localization. There's also a POT (Template) file, that simply contains +binary to be interpreted by gettext when doing localization. There's also a POT (Template) file, which simply contains all existing keys from your source files, and can be used as a guide to generate and update all PO files. Those template -files are not mandatory: depending on the tool you're using to do l10n, you can go just fine with only PO/MO files. -You'll always have one pair of PO/MO files per language and region, but only one POT per domain. +files are not mandatory: depending on the tool you are using to do l10n, you can go just fine with only PO/MO files. +You will always have one pair of PO/MO files per language and region, but only one POT per domain. ### Domains There are some cases, in big projects, where you might need to separate translations when the same words convey -different meaning given a context. In those cases, you split them into different _domains_. They're basically named +different meaning given a context. In those cases, you split them into different _domains_. They are, basically, named groups of POT/PO/MO files, where the filename is the said _translation domain_. Small and medium-sized projects usually, -for simplicity, use only one domain; its name is arbitrary, but we will be using "main" for our code samples. +for simplicity, use only one domain; its name is arbitrary, but we will be using "main" for our code samples. In [Symfony] projects, for example, domains are used to separate the translation for validation messages. #### Locale code -A locale is simply a code that identifies one version of a language. It's defined following the [ISO 639-1][639-1] and +A locale is simply a code that identifies one version of a language. It is defined following the [ISO 639-1][639-1] and [ISO 3166-1 alpha-2][3166-1] specs: two lower-case letters for the language, optionally followed by an underline and two upper-case letters identifying the country or regional code. For [rare languages][rare], three letters are used. For some speakers, the country part may seem redundant. In fact, some languages have dialects in different countries, such as Austrian German (`de_AT`) or Brazilian Portuguese (`pt_BR`). The second part is used to distinguish -between those dialects - when it's not present, it's taken as a "generic" or "hybrid" version of the language. +between those dialects - when it is not present, it is taken as a "generic" or "hybrid" version of the language. ### Directory structure -To use Gettext, we will need to adhere to a specific structure of folders. First, you'll need to select an arbitrary -root for your l10n files in your source repository. Inside it, you'll have a folder for each needed locale, and a fixed -`LC_MESSAGES` folder that will contain all your PO/MO pairs. Example: +To use Gettext, we will need to adhere to a specific structure of folders. First, you will need to select an arbitrary +root for your l10n files in your source repository. Inside it, you will have a folder for each needed locale, and a +fixed `LC_MESSAGES` folder that will contain all your PO/MO pairs. Example: {% highlight console %} @@ -117,9 +120,9 @@ root for your l10n files in your source repository. Inside it, you'll have a fol ### Plural forms As we said in the introduction, different languages might sport different plural rules. However, gettext saves us from -this trouble once again. When creating a new `.po` file, you'll have to declare the [plural rules][plural] for that +this trouble once again. When creating a new `.po` file, you will have to declare the [plural rules][plural] for that language, and translated pieces that are plural-sensitive will have a different form for each of those rules. When -calling Gettext in code, you'll have to specify the number related to the sentence, and it will work out the correct +calling Gettext in code, you will have to specify the number related to the sentence, and it will work out the correct form to use - even using string substitution if needed. Plural rules include the number of plurals available and a boolean test with `n` that would define in which rule the @@ -133,13 +136,13 @@ Now that you understood the basis of how plural rules works - and if you didn't, on the [LingoHub tutorial][lingohub_plurals] -, you might want to copy the ones you need from a [list][plural] instead of writing them by hand. -When calling out Gettext to do localization on sentences with counters, you'll have to give him the +When calling out Gettext to do localization on sentences with counters, you will have to give him the related number as well. Gettext will work out what rule should be in effect and use the correct localized version. You will need to include in the `.po` file a different sentence for each plural rule defined. ### Sample implementation After all that theory, let's get a little practical. Here's an excerpt of a `.po` file - don't mind with its format, -but instead the overall content, you'll learn how to edit it easily later: +but with the overall content instead; you will learn how to edit it easily later: {% highlight po %} msgid "" @@ -148,7 +151,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -msgid "We're now translating some strings" +msgid "We are now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" @@ -164,50 +167,50 @@ The first section works like a header, having the `msgid` and `msgstr` especiall plural forms and other things that are less relevant. The second section translates a simple string from English to Brazilian Portuguese, and the third does the same, but leveraging string replacement from [`sprintf`][sprintf] so the -translation may contain the user name and visit date. +translation may contain the user name and visit date. The last section is a sample of pluralization forms, displaying the singular and plural version as `msgid` in English and their corresponding translations as `msgstr` 0 and 1 (following the number given by the plural rule). There, string replacement is used as well so the number can be seen -directly in the sentence, by using `%d`. The plural forms always have two `msgid` (singular and plural), so it's -advised to not use a complex language as the source of translation. +directly in the sentence, by using `%d`. The plural forms always have two `msgid` (singular and plural), so it is +advised not to use a complex language as the source of translation. ### Discussion on l10n keys -As you might have noticed, we're using as source ID the actual sentence in English. That `msgid` is the same used +As you might have noticed, we are using as source ID the actual sentence in English. That `msgid` is the same used throughout all your `.po` files, meaning other languages will have the same format and the same `msgid` fields but translated `msgstr` lines. Talking about translation keys, there are two main "schools" here: -1. _`msgid` as a real sentence_. - The main advantages are: +1. _`msgid` as a real sentence_. + The main advantages are: - if there are pieces of the software untranslated in any given language, the key displayed will still maintain some meaning. Example: if you happen to translate by heart from English to Spanish but need help to translate to French, you might publish the new page with missing French sentences, and parts of the website would be displayed in English instead; - - it's much easier for the translator to understand what's going on and make a proper translation based on the + - it is much easier for the translator to understand what's going on and do a proper translation based on the `msgid`; - it gives you "free" l10n for one language - the source one; - The only disadvantage: if you need to change the actual text, you would need to replace the same `msgid` across several language files. -2. _`msgid` as a unique, structured key_. +2. _`msgid` as a unique, structured key_. It would describe the sentence role in the application in a structured way, including the template or part where the string is located instead of its content. - - it's a great way to have the code organized, separating the text content from the template logic. + - it is a great way to have the code organized, separating the text content from the template logic. - however, that could bring problems to the translator that would miss the context. A source language file would be needed as a basis for other translations. Example: the developer would ideally have an `en.po` file, that translators would read to understand what to write in `fr.po` for instance. - missing translations would display meaningless keys on screen (`top_menu.welcome` instead of `Hello there, User!` - on the said untranslated French page). That's good it as would force translation to be complete before publishing - - but bad as translation issues would be really awful in the interface. Some libraries, though, include an option to - specify a given language as "fallback", having a similar behavior as the other approach. + on the said untranslated French page). That is good it as would force translation to be complete before publishing - + however, bad as translation issues would be remarkably awful in the interface. Some libraries, though, include an + option to specify a given language as "fallback", having a similar behavior as the other approach. -The [Gettext manual][manual] favors the first approach as, in general, it's easier for translators and users in -case of trouble. That's how we will be working here as well. However, the [Symfony documentation][symfony-keys] favors +The [Gettext manual][manual] favors the first approach as, in general, it is easier for translators and users in +case of trouble. That is how we will be working here as well. However, the [Symfony documentation][symfony-keys] favors keyword-based translation, to allow for independent changes of all translations without affecting templates as well. ### Everyday usage -In a common application, you would use some Gettext functions while writing static text in your pages. Those sentences +In a typical application, you would use some Gettext functions while writing static text in your pages. Those sentences would then appear in `.po` files, get translated, compiled into `.mo` files and then, used by Gettext when rendering the actual interface. Given that, let's tie together what we have discussed so far in a step-by-step example: @@ -246,7 +249,7 @@ call. More on domain configuration in the next example. * @return bool */ function valid($locale) { - return in_array($locale, ['en_US', 'en', 'pt_BR', 'pt', 'es_ES', 'es'); + return in_array($locale, ['en_US', 'en', 'pt_BR', 'pt', 'es_ES', 'es']); } //setting the source/default locale, for informational purposes @@ -296,68 +299,75 @@ textdomain('main'); {% endhighlight %} #### 3. Preparing translation for the first run -To make matters easier - and one of the powerful advantages Gettext has over custom framework i18n packages - is its -custom file type. "Oh man, that's quite hard to understand and edit by hand, a simple array would be easier!" Make no -mistake, applications like [Poedit] are here to help - _a lot_. You can get the program from -[their website][poedit_download], it's free and available for all platforms. It's a pretty easy tool to get used to, -and a very powerful one at the same time - using all powerful features Gettext has available. - -In the first run, you should select "File > New Catalog" from the menu. There you'll have a small screen where we will -set the terrain so everything else runs smoothly. You'll be able to find those settings later through -"Catalog > Properties": - -- Project name and version, Translation Team and email address: useful information that goes in the `.po` file header; -- Language: here you should use that format we mentioned before, such as `en_US` or `pt_BR`; -- Charsets: UTF-8, preferably; -- Source charset: set here the charset used by your PHP files - probably UTF-8 as well, right? -- plural forms: here go those rules we mentioned before - there's a link in there with samples as well; -- Source paths: here you must include all folders from the project where `gettext()` (and siblings) will happen - this -is usually your templates folder(s) -- Source keywords: this last part is filled by default, but you might need to alter it later - and is one of the -powerful points of Gettext. The underlying software knows how the `gettext()` calls look like in several programming -languages, but you might as well create your own translation forms. This will be discussed later in the "Tips" section. - -After setting those points you'll be prompted to save the file - using that directory structure we mentioned as well, -and then it will run a scan through your source files to find the localization calls. They'll be fed empty into the -translation table, and you'll start typing in the localized versions of those strings. Save it and a `.mo` file will be -(re)compiled into the same folder and ta-dah: your project is internationalized. +One of the great advantages Gettext has over custom framework i18n packages is its extensive and powerful file format. +"Oh man, that’s quite hard to understand and edit by hand, a simple array would be easier!" Make no mistake, +applications like [Poedit] are here to help - _a lot_. You can get the program from [their website][poedit_download], +it’s free and available for all platforms. It’s a pretty easy tool to get used to, and a very powerful one at the same +time - using all features Gettext has available. This guide is based on PoEdit 1.8. + +In the first run, you should select “File > New...” from the menu. You’ll be asked straight ahead for the language: +here you can select/filter the language you want to translate to, or use that format we mentioned before, such as +`en_US` or `pt_BR`. + +Now, save the file - using that directory structure we mentioned as well. Then you should click “Extract from sources”, +and here you’ll configure various settings for the extraction and translation tasks. You’ll be able to find all those +later through “Catalog > Properties”: + +- Source paths: here you must include all folders from the project where `gettext()` (and siblings) are called - this +is usually your templates/views folder(s). This is the only mandatory setting; +- Translation properties: + - Project name and version, Team and Team’s email address: useful information that goes in the .po file header; + - Plural forms: here go those rules we mentioned before - there’s a link in there with samples as well. You can + leave it with the default option most of the time, as PoEdit already includes a handy database of plural rules for + many languages. + - Charsets: UTF-8, preferably; + - Source code charset: set here the charset used by your codebase - probably UTF-8 as well, right? +- Source keywords: The underlying software knows how `gettext()` and similar function calls look like in several +programming languages, but you might as well create your own translation functions. It will be here you’ll add those +other methods. This will be discussed later in the “Tips” section. + +After setting those points it will run a scan through your source files to find all the localization calls. After every +scan PoEdit will display a summary of what was found and what was removed from the source files. New entries will fed +empty into the translation table, and you’ll start typing in the localized versions of those strings. Save it and a .mo +file will be (re)compiled into the same folder and ta-dah: your project is internationalized. #### 4. Translating strings -As you may have noticed before, there are two main types of localized strings: simple ones and the ones with plural -forms. The first ones have simply two boxes: source and localized string. The source string can't be modified as +As you may have noticed before, there are two main types of localized strings: simple ones and those with plural +forms. The first ones have simply two boxes: source and localized string. The source string cannot be modified as Gettext/Poedit do not include the powers to alter your source files - you should change the source itself and rescan the files. Tip: you may right-click a translation line and it will hint you with the source files and lines where that -string is being used. +string is being used. On the other hand, plural form strings include two boxes to show the two source strings, and tabs so you can configure the different final forms. Whenever you change your sources and need to update the translations, just hit Refresh and Poedit will rescan the code, removing non-existent entries, merging the ones that changed and adding new ones. It may also try to guess some translations, based on other ones you did. Those guesses and the changed entries will receive a "Fuzzy" marker, -indicating it needs review, being highlighted in the list. It's also useful if you have a translation team and someone -tries to write something they're not sure about: just mark Fuzzy and someone else will review later. +indicating it needs review, appearing golden in the list. It is also useful if you have a translation team and someone +tries to write something they are not sure about: just mark Fuzzy, and someone else will review later. -Finally, it's advised to leave "View > Untranslated entries first" marked, as it will help you _a lot_ to not forget +Finally, it is advised to leave "View > Untranslated entries first" marked, as it will help you _a lot_ to not forget any entry. From that menu, you can also open parts of the UI that allow you to leave contextual information for translators if needed. ### Tips & Tricks #### Possible caching issues -If you're running PHP as a module on Apache (`mod_php`), you might face issues with the `.mo` file being cached. It -happens the first time it's read, and then, to update it, you might need to restart the server. On Nginx and PHP5 it +If you are running PHP as a module on Apache (`mod_php`), you might face issues with the `.mo` file being cached. It +happens the first time it is read, and then, to update it, you might need to restart the server. On Nginx and PHP5 it usually takes only a couple of page refreshes to refresh the translation cache, and on PHP7 it is rarely needed. #### Additional helper functions -As preferred by many people, it's easier to use `_()` instead of `gettext()`. Many custom i18n libraries from -frameworks use something similar to `t()` as well, to make translated code shorter. However, that's the only function +As preferred by many people, it is easier to use `_()` instead of `gettext()`. Many custom i18n libraries from +frameworks use something similar to `t()` as well, to make translated code shorter. However, that is the only function that sports a shortcut. You might want to add in your project some others, such as `__()` or `_n()` for `ngettext()`, or maybe a fancy `_r()` that would join `gettext()` and `sprintf()` calls. Other libraries, such as [oscarotero's Gettext][oscarotero] also provide helper functions like these. In those cases, you'll need to instruct the Gettext utility on how to extract the strings from those new functions. -Don't be afraid, it's very easy. It's just a field in the `.po` file, or a Settings screen on Poedit. In the editor, -that option is inside "Catalog > Properties > Source keywords". You need to include there the specifications of those +Don't be afraid; it is very easy. It is just a field in the `.po` file, or a Settings screen on Poedit. In the editor, +that option is inside "Catalog > Properties > Source keywords". Remember: Gettext already knows the default functions +for many languages, so don’t be afraid if that list seems empty. You need to include there the specifications of those new functions, following [a specific format][func_format]: - if you create something like `t()` that simply returns the translation for a string, you can specify it as `t`. @@ -375,31 +385,31 @@ After including those new rules in the `.po` file, a new scan will bring in your * [Wikipedia: i18n and l10n](https://en.wikipedia.org/wiki/Internationalization_and_localization) * [Wikipedia: Gettext](https://en.wikipedia.org/wiki/Gettext) * [LingoHub: PHP internationalization with gettext tutorial][lingohub] -* [PHP Manual: Gettext](http://php.net/manual/en/book.gettext.php) +* [PHP Manual: Gettext](https://php.net/manual/en/book.gettext.php) * [Gettext Manual][manual] [Poedit]: https://poedit.net [poedit_download]: https://poedit.net/download [lingohub]: https://lingohub.com/blog/2013/07/php-internationalization-with-gettext-tutorial/ [lingohub_plurals]: https://lingohub.com/blog/2013/07/php-internationalization-with-gettext-tutorial/#Plurals -[plural]: http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html +[plural]: https://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html [gettext]: https://en.wikipedia.org/wiki/Gettext -[manual]: http://www.gnu.org/software/gettext/manual/gettext.html +[manual]: https://www.gnu.org/software/gettext/manual/gettext.html [639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes -[3166-1]: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 -[rare]: http://www.gnu.org/software/gettext/manual/gettext.html#Rare-Language-Codes +[3166-1]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 +[rare]: https://www.gnu.org/software/gettext/manual/gettext.html#Rare-Language-Codes [func_format]: https://www.gnu.org/software/gettext/manual/gettext.html#Language-specific-options [oscarotero]: https://github.com/oscarotero/Gettext [symfony]: https://symfony.com/doc/current/components/translation.html [zend]: https://docs.zendframework.com/zend-i18n/translation [laravel]: https://laravel.com/docs/master/localization -[yii]: http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html -[intl]: http://br2.php.net/manual/en/intro.intl.php -[ICU project]: http://www.icu-project.org +[yii]: https://www.yiiframework.com/doc/guide/2.0/en/tutorial-i18n +[intl]: https://php.net/manual/en/intro.intl.php +[ICU project]: https://www.icu-project.org [symfony-keys]: https://symfony.com/doc/current/components/translation/usage.html#creating-translations -[sprintf]: http://php.net/manual/en/function.sprintf.php -[func]: http://php.net/manual/en/function.gettext.php -[n_func]: http://php.net/manual/en/function.ngettext.php -[d_func]: http://php.net/manual/en/function.dgettext.php -[dn_func]: http://php.net/manual/en/function.dngettext.php +[sprintf]: https://php.net/manual/en/function.sprintf.php +[func]: https://php.net/manual/en/function.gettext.php +[n_func]: https://php.net/manual/en/function.ngettext.php +[d_func]: https://php.net/manual/en/function.dgettext.php +[dn_func]: https://php.net/manual/en/function.dngettext.php diff --git a/_posts/06-01-01-Dependency-Injection.md b/_posts/06-01-01-Dependency-Injection.md index 4a2e9e115..74cd6a072 100644 --- a/_posts/06-01-01-Dependency-Injection.md +++ b/_posts/06-01-01-Dependency-Injection.md @@ -5,7 +5,7 @@ anchor: dependency_injection # 依赖注入 {#dependency_injection_title} -出自维基百科 [Wikipedia](http://en.wikipedia.org/wiki/Dependency_injection): +出自维基百科 [Wikipedia](https://wikipedia.org/wiki/Dependency_injection): > 依赖注入是一种允许我们从硬编码的依赖中解耦出来,从而在运行时或者编译时能够修改的软件设计模式。 diff --git a/_posts/06-03-01-Complex-Problem.md b/_posts/06-03-01-Complex-Problem.md index c5a240e3f..522393a8e 100644 --- a/_posts/06-03-01-Complex-Problem.md +++ b/_posts/06-03-01-Complex-Problem.md @@ -12,7 +12,7 @@ title: 复杂的问题 顾名思义,一个系统通过组织控制和对象的完全分离来实现"控制反转"。对于依赖注入,这就意味着通过在系统的其他地方控制和实例化依赖对象,从而实现了解耦。 -一些 PHP 框架很早以前就已经实现控制反转了,但是问题是,应该反转哪部分以及到什么程度?比如, MVC 框架通常会提供超类或者基本的控制器类以便其他控制器可以通过继承来获得相应的依赖。这就是控制反转的例子,但是这种方法是直接移除了依赖而不是减轻了依赖。 +一些 PHP 框架很早以前就已经实现控制反转了,但是问题是,我们应该反转哪部分以及到什么程度?比如, MVC 框架通常会提供超类或者基本的控制器类以便其他控制器可以通过继承来获得相应的依赖。这就是控制反转的例子,但是这种方法是直接移除了依赖而不是减轻了依赖。 依赖注入允许我们通过按需注入的方式更加优雅地解决这个问题,完全不需要任何耦合。 @@ -20,6 +20,60 @@ title: 复杂的问题 依赖反转准则是面向对象设计准则 S.O.L.I.D 中的 "D" ,倡导 *"依赖于抽象而不是具体"*。简单来说就是依赖应该是接口/约定或者抽象类,而不是具体的实现。我们能很容易重构前面的例子,使之遵循这个准则 +### 面向对象五大原则(S.O.L.I.D) + +#### 单一替换原则 + +The Single Responsibility Principle is about actors and high-level architecture. It states that “A class should have +only one reason to change.” This means that every class should _only_ have responsibility over a single part of the +functionality provided by the software. The largest benefit of this approach is that it enables improved code +_reusability_. By designing our class to do just one thing, we can use (or re-use) it in any other program without +changing it. + +#### 开闭原则 + +The Open/Closed Principle is about class design and feature extensions. It states that “Software entities (classes, +modules, functions, etc.) should be open for extension, but closed for modification.” This means that we should design +our modules, classes and functions in a way that when a new functionality is needed, we should not modify our existing +code but rather write new code that will be used by existing code. Practically speaking, this means that we should write +classes that implement and adhere to _interfaces_, then type-hint against those interfaces instead of specific classes. + +The largest benefit of this approach is that we can very easily extend our code with support for something new without +having to modify existing code, meaning that we can reduce QA time, and the risk for negative impact to the application +is substantially reduced. We can deploy new code, faster, and with more confidence. + +#### 里氏替换原则 + +The Liskov Substitution Principle is about subtyping and inheritance. It states that “Child classes should never break +the parent class’ type definitions.” Or, in Robert C. Martin’s words, “Subtypes must be substitutable for their base +types.” + +For example, if we have a `FileInterface` interface which defines an `embed()` method, and we have `Audio` and `Video` +classes which both implement the `embed()` method, then we can expect that the usage of the `embed()` method will always +do the thing that we intend. If we later create a `PDF` class or a `Gist` class which implement the `FileInterface` +interface, we will already know and understand what the `embed()` method will do. The largest benefit of this approach +is that we have the ability to build flexible and easily-configurable programs, because when we change one object of a +type (e.g., `FileInterface`) to another we don't need to change anything else in our program. + +#### 接口隔离原则 + +The Interface Segregation Principle (ISP) is about _business-logic-to-clients_ communication. It states that “No client +should be forced to depend on methods it does not use.” This means that instead of having a single monolithic interface +that all conforming classes need to implement, we should instead provide a set of smaller, concept-specific interfaces +that a conforming class implements one or more of. + +For example, a `Car` or `Bus` class would be interested in a `steeringWheel()` method, but a `Motorcycle` or `Tricycle` +class would not. Conversely, a `Motorcycle` or `Tricycle` class would be interested in a `handlebars()` method, but a +`Car` or `Bus` class would not. There is no need to have all of these types of vehicles implement support for both +`steeringWheel()` as well as `handlebars()`, so we should break-apart the source interface. + +#### 依赖倒置原则 + +The Dependency Inversion Principle is about removing hard-links between discrete classes so that new functionality can +be leveraged by passing a different class. It states that one should *"Depend on Abstractions. Do not depend on +concretions."*. Put simply, this means our dependencies should be interfaces/contracts or abstract classes rather than +concrete implementations. We can easily refactor the above example to follow this principle. + {% highlight php %} execute(); 对于写入操作,例如 INSERT 或者 UPDATE,进行[数据过滤](#data_filtering)并对其他内容进行清理(去除 HTML 标签,Javascript 等等)是尤其重要的。PDO 只会为 SQL 进行清理,并不会为你的应用做任何处理。 -* [了解 PDO] +* [了解 PDO][Learn about PDO] 你也应该知道数据库连接有时会耗尽全部资源,如果连接没有被隐式地关闭的话,有可能会造成可用资源枯竭的情况。不过这通常在其他语言中更为常见一些。使用 PDO 你可以通过销毁(destroy)对象,也就是将值设为 NULL,来隐式地关闭这些连接,确保所有剩余的引用对象的连接都被删除。如果你没有亲自做这件事情,PHP 会在你的脚本结束的时候自动为你完成 —— 除非你使用的是持久链接。 -* [了解 PDO 连接] +* [了解 PDO 连接][Learn about PDO connections] -[pdo]: http://php.net/pdo +[pdo]: https://secure.php.net/pdo [SQL Injection]: http://wiki.hashphp.org/Validation -[了解 PDO]: http://php.net/book.pdo -[了解 PDO 连接]: http://php.net/pdo.connections \ No newline at end of file +[Learn about PDO]: https://secure.php.net/book.pdo +[Learn about PDO connections]: https://secure.php.net/pdo.connections \ No newline at end of file diff --git a/_posts/07-04-01-Interacting-via-Code.md b/_posts/07-04-01-Interacting-via-Code.md index f98e5b8d8..73924e11a 100644 --- a/_posts/07-04-01-Interacting-via-Code.md +++ b/_posts/07-04-01-Interacting-via-Code.md @@ -30,7 +30,8 @@ function getAllFoos($db) { return $db->query('SELECT * FROM table'); } -foreach (getAllFoos($db) as $row) { +$results = getAllFoos($db); +foreach ($results as $row) { echo "
  • ".$row['field1']." - ".$row['field1']."
  • "; // BAD!! } {% endhighlight %} @@ -43,17 +44,17 @@ foreach (getAllFoos($db) as $row) { {% highlight php %} getAllFoos(); -// Show the view +// 显示到视图 include 'views/foo-list.php'; {% endhighlight %} @@ -81,15 +82,15 @@ class FooModel {% highlight php %} - - +
  • -
  • {% endhighlight %} 向大多数现代框架的做法学习是很有必要的,尽管多了一些手动的工作。你可以并不需要每一次都完全这么做,但将太多的表示逻辑层代码和数据库交互掺杂在一些将会为你在想要对程序进行[单元测试](/#unit-testing)时带来真正的麻烦。 -[PHPBridge] 具有一项非常棒的资源叫做[创建一个数据类]。它包含了非常相似的逻辑而且非常适合刚刚习惯数据库交互概念的开发者使用。 +[PHPBridge] 具有一项非常棒的资源叫做[创建一个数据类][Creating a Data Class]。它包含了非常相似的逻辑而且非常适合刚刚习惯数据库交互概念的开发者使用。 -[MVC]: http://code.tutsplus.com/tutorials/mvc-for-noobs--net-10488 -[PHPBridge]: http://phpbridge.org/ -[创建一个数据类]: http://phpbridge.org/intro-to-php/creating_a_data_class +[MVC]: https://code.tutsplus.com/tutorials/mvc-for-noobs--net-10488 +[PHPBridge]: https://phpbridge.org/docs/ +[Creating a Data Class]: https://phpbridge.org/intro-to-php/creating_a_data_class diff --git a/_posts/07-05-01-Abstraction-Layers.md b/_posts/07-05-01-Abstraction-Layers.md index fd7b3b2a1..2cb1fd519 100644 --- a/_posts/07-05-01-Abstraction-Layers.md +++ b/_posts/07-05-01-Abstraction-Layers.md @@ -16,10 +16,10 @@ anchor: databases_abstraction_layers * [Zend-db][4] -[1]: http://php.net/book.pdo -[2]: http://www.doctrine-project.org/projects/dbal.html +[1]: https://secure.php.net/book.pdo +[2]: https://www.doctrine-project.org/projects/dbal.html [4]: https://packages.zendframework.com/docs/latest/manual/en/index.html#zendframework/zend-db [6]: https://github.com/auraphp/Aura.Sql [7]: http://propelorm.org/ -[psr0]: http://www.php-fig.org/psr/psr-0/ -[psr4]: http://www.php-fig.org/psr/psr-4/ +[psr0]: https://www.php-fig.org/psr/psr-0/ +[psr4]: https://www.php-fig.org/psr/psr-4/ diff --git a/_posts/08-04-01-Compiled-Templates.md b/_posts/08-04-01-Compiled-Templates.md index 0fb78f73c..5c3d5ed46 100644 --- a/_posts/08-04-01-Compiled-Templates.md +++ b/_posts/08-04-01-Compiled-Templates.md @@ -64,7 +64,7 @@ title: 编译模板 [article_templating_engines]: http://fabien.potencier.org/article/34/templating-engines-in-php -[Twig]: http://twig.sensiolabs.org/ +[Twig]: https://twig.symfony.com/ [Brainy]: https://github.com/box/brainy -[Smarty]: http://www.smarty.net/ -[Mustache]: http://mustache.github.io/ +[Smarty]: https://www.smarty.net/ +[Mustache]: https://mustache.github.io/ diff --git a/_posts/08-05-01-Further-Reading.md b/_posts/08-05-01-Further-Reading.md index fee91b184..ec71a9f20 100644 --- a/_posts/08-05-01-Further-Reading.md +++ b/_posts/08-05-01-Further-Reading.md @@ -9,23 +9,23 @@ title: 延伸阅读 ### 文章与教程 * [Templating Engines in PHP](http://fabien.potencier.org/article/34/templating-engines-in-php) -* [An Introduction to Views & Templating in CodeIgniter](http://code.tutsplus.com/tutorials/an-introduction-to-views-templating-in-codeigniter--net-25648) -* [Getting Started With PHP Templating](http://www.smashingmagazine.com/2011/10/17/getting-started-with-php-templating/) -* [Roll Your Own Templating System in PHP](http://code.tutsplus.com/tutorials/roll-your-own-templating-system-in-php--net-16596) +* [An Introduction to Views & Templating in CodeIgniter](https://code.tutsplus.com/tutorials/an-introduction-to-views-templating-in-codeigniter--net-25648) +* [Getting Started With PHP Templating](https://www.smashingmagazine.com/2011/10/getting-started-with-php-templating/) +* [Roll Your Own Templating System in PHP](https://code.tutsplus.com/tutorials/roll-your-own-templating-system-in-php--net-16596) * [Master Pages](https://laracasts.com/series/laravel-from-scratch/episodes/7) -* [Working With Templates in Symfony 2](http://code.tutsplus.com/tutorials/working-with-templates-in-symfony-2--cms-21172) +* [Working With Templates in Symfony 2](https://code.tutsplus.com/tutorials/working-with-templates-in-symfony-2--cms-21172) * [Writing Safer Templates](https://github.com/box/brainy/wiki/Writing-Safe-Templates) ### 类库 * [Aura.View](https://github.com/auraphp/Aura.View) *(native)* -* [Blade](http://laravel.com/docs/blade) *(compiled, framework specific)* +* [Blade](https://laravel.com/docs/blade) *(compiled, framework specific)* * [Brainy](https://github.com/box/brainy) *(compiled)* * [Dwoo](http://dwoo.org/) *(compiled)* * [Latte](https://github.com/nette/latte) *(compiled)* * [Mustache](https://github.com/bobthecow/mustache.php) *(compiled)* -* [PHPTAL](http://phptal.org/) *(compiled)* +* [PHPTAL](https://phptal.org/) *(compiled)* * [Plates](http://platesphp.com/) *(native)* -* [Smarty](http://www.smarty.net/) *(compiled)* -* [Twig](http://twig.sensiolabs.org/) *(compiled)* -* [Zend\View](http://framework.zend.com/manual/2.3/en/modules/zend.view.quick-start.html) *(native, framework specific)* +* [Smarty](https://www.smarty.net/) *(compiled)* +* [Twig](https://twig.symfony.com/) *(compiled)* +* [Zend\View](https://framework.zend.com/manual/2.3/en/modules/zend.view.quick-start.html) *(native, framework specific)* diff --git a/_posts/09-02-01-Errors.md b/_posts/09-02-01-Errors.md index c222e92dc..0ed11b0e4 100644 --- a/_posts/09-02-01-Errors.md +++ b/_posts/09-02-01-Errors.md @@ -66,7 +66,8 @@ variable: foo` 或 `PHP Notice: Undefined index: bar` 。 {% highlight php %} 测试驱动开发 (TDD) 是一种以非常短的开发周期不断迭代的软件开发过程:首先开发者对将要实现的功能或者新的方法写一个失败的自动化测试用例,然后就去写代码来通过这个测试用例,最终通过重构代码让一其达到可接受的水准。**Kent Beck**, 这个技术创造者或者说重新发现者,在2003年声明TDD 鼓励简单的设计和激励信心。 @@ -23,12 +23,12 @@ anchor: test_driven_development * [atoum](https://github.com/atoum/atoum) * [Kahlan](https://github.com/crysalead/kahlan) -* [Peridot](http://peridot-php.github.io/) +* [Peridot](https://peridot-php.github.io/) * [SimpleTest](http://simpletest.org) ### 集成测试 -[Wikipedia](http://en.wikipedia.org/wiki/Test-driven_development) 上的定义: +[Wikipedia](https://wikipedia.org/wiki/Integration_testing) 上的定义: > 集成测试 (有时候称为集成和测试,缩写为 `I&T`)是把各个模块组合在一起进行整体测试的软件测试阶段。它处于单元测试之后,验收测试之前。集成测试将已经经过了单元测试的模块做为输入模块,组合成一个整体,然后运行集成测试用例,然后输出一个可以进行系统测试的系统。 @@ -40,7 +40,7 @@ anchor: test_driven_development #### 功能测试的工具 -- [Selenium](http://docs.seleniumhq.org/) -- [Mink](http://mink.behat.org/en/latest/) -- [Codeception](http://codeception.com/) 是一个全栈的测试框架包括验收性测试工具。 -- [Storyplayer](http://datasift.github.io/storyplayer/) 是一个全栈的测试框架并且支持随时创建和销毁测试环境。 +* [Selenium](https://docs.seleniumhq.org/) +* [Mink](http://mink.behat.org/) +* [Codeception](https://codeception.com/) 是一个全栈的测试框架包括验收性测试工具。 +* [Storyplayer](https://datasift.github.io/storyplayer/) 是一个全栈的测试框架并且支持随时创建和销毁测试环境。 diff --git a/_posts/11-03-01-Behavior-Driven-Development.md b/_posts/11-03-01-Behavior-Driven-Development.md index 1d03dd329..2d9052ee4 100644 --- a/_posts/11-03-01-Behavior-Driven-Development.md +++ b/_posts/11-03-01-Behavior-Driven-Development.md @@ -19,7 +19,7 @@ title: 行为驱动开发 * [Codeception] 是一个使用 BDD 准则的全栈测试框架。 [Behat]: http://behat.org/ -[Cucumber]: http://cukes.info/ -[PHPSpec]: http://www.phpspec.net/ -[RSpec]: http://rspec.info/ -[Codeception]: http://codeception.com/ +[Cucumber]: https://cucumber.io/ +[PHPSpec]: https://www.phpspec.net/ +[RSpec]: https://rspec.info/ +[Codeception]: https://codeception.com/ diff --git a/_posts/11-04-01-Complementary-Testing-Tools.md b/_posts/11-04-01-Complementary-Testing-Tools.md index 616538dba..6645aa21f 100644 --- a/_posts/11-04-01-Complementary-Testing-Tools.md +++ b/_posts/11-04-01-Complementary-Testing-Tools.md @@ -13,10 +13,15 @@ title: 共享服务器 * [Selenium] 是一个浏览器自动化工具 [integrated with PHPUnit] * [Mockery] 是一个可以跟 [PHPUnit] 或者 [PHPSpec] 整合的 Mock 对象框架 * [Prophecy] 是个有自己的想法,且非常强大灵活的 PHP 对象 mocking 框架。它整合了 [PHPSpec] 并且可以和 [PHPUnit] 一起使用 +* [php-mock] 一个 Mock PHP 原生方法的库 +* [Infection] is a PHP implementation of [Mutation Testing] to help to measure the effectiveness of your tests. -[Selenium]: http://seleniumhq.org/ +[Selenium]: https://www.seleniumhq.org/ [integrated with PHPUnit]: https://github.com/giorgiosironi/phpunit-selenium/ [Mockery]: https://github.com/padraic/mockery -[PHPUnit]: http://phpunit.de/ -[PHPSpec]: http://www.phpspec.net/ +[PHPUnit]: https://phpunit.de/ +[PHPSpec]: https://www.phpspec.net/ [Prophecy]: https://github.com/phpspec/prophecy +[php-mock]: https://github.com/php-mock/php-mock +[Infection]: https://github.com/infection/infection +[Mutation Testing]: https://en.wikipedia.org/wiki/Mutation_testing diff --git a/_posts/12-03-01-Virtual-or-Dedicated-Servers.md b/_posts/12-03-01-Virtual-or-Dedicated-Servers.md index 17e1b8379..2e63e7ab4 100644 --- a/_posts/12-03-01-Virtual-or-Dedicated-Servers.md +++ b/_posts/12-03-01-Virtual-or-Dedicated-Servers.md @@ -34,16 +34,16 @@ Apache 有多种方式运行 PHP,最常见的方式就是使用 mode_php5 的 * [配置 Apache 通过 mod_proxy_fcgi 使用 PHP-FPM][tutorial-mod_proxy_fcgi] -[nginx]: http://nginx.org/ -[phpfpm]: http://php.net/install.fpm +[nginx]: https://nginx.org/ +[phpfpm]: https://secure.php.net/install.fpm [secure-nginx-phpfpm]: https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/ -[apache-modules]: http://httpd.apache.org/docs/2.4/mod/ -[prefork MPM]: http://httpd.apache.org/docs/2.4/mod/prefork.html -[worker MPM]: http://httpd.apache.org/docs/2.4/mod/worker.html -[event MPM]: http://httpd.apache.org/docs/2.4/mod/event.html -[apache]: http://httpd.apache.org/ -[apache-MPM]: http://httpd.apache.org/docs/2.4/mod/mpm_common.html +[apache-modules]: https://httpd.apache.org/docs/2.4/mod/ +[prefork MPM]: https://httpd.apache.org/docs/2.4/mod/prefork.html +[worker MPM]: https://httpd.apache.org/docs/2.4/mod/worker.html +[event MPM]: https://httpd.apache.org/docs/2.4/mod/event.html +[apache]: https://httpd.apache.org/ +[apache-MPM]: https://httpd.apache.org/docs/2.4/mod/mpm_common.html [mod_fastcgi]: https://blogs.oracle.com/opal/entry/php_fpm_fastcgi_process_manager -[mod_fcgid]: http://httpd.apache.org/mod_fcgid/ +[mod_fcgid]: hhttps://httpd.apache.org/mod_fcgid/ [mod_proxy_fcgi]: https://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html [tutorial-mod_proxy_fcgi]: https://serversforhackers.com/video/apache-and-php-fpm diff --git a/_posts/12-05-01-Building-your-Application.md b/_posts/12-05-01-Building-your-Application.md index 3fe6f8027..5accedef7 100644 --- a/_posts/12-05-01-Building-your-Application.md +++ b/_posts/12-05-01-Building-your-Application.md @@ -27,7 +27,7 @@ anchor: building_and_deploying_your_application [Capistrano] 是一个为 *中高级程序员* 准备的系统,以一种结构化、可复用的方式在一台或多台远程机器上执行命令。对于部署 Ruby on Rails 的应用,它提供了预定义的配置,不过也可以用它来 **部署 PHP 应用** 。如果要成功的使用 Capistrano ,需要一定的 Ruby 和 Rake 的知识。 -对 Capistrano 感兴趣的 PHP 开发者可以阅读 Dave Gardner 的博文 [PHP Deployment with Capistrano][phpdeploy_capistrano] ,来作为一个很好的开始。 +[Ansistrano]是几个 Ansible 角色,可轻松管理脚本编写应用程序(例如PHP,Python和Ruby)的部署过程(部署和回滚)。 它是[Capistrano]的 Ansible 端口。它已经被很多PHP公司所使用。 [Rocketeer] 从 Laravel 框架中得到了很多灵感。 目标是默认智能化配置、高速、优雅的自动化部署工具。他支持多服务器,多阶段,并行部署等功能。工具的扩展性极强,并且是由 PHP 编写。 @@ -38,7 +38,6 @@ anchor: building_and_deploying_your_application #### 延伸阅读: * [Automate your project with Apache Ant][apache_ant_tutorial] -* [Expert PHP Deployments][expert_php_deployments] - free book on deployment with Capistrano, Phing and Vagrant. * [Deploying PHP Applications][deploying_php_applications] - paid book on best practices and tools for PHP deployment. ### 服务器布置 Server Provisioning @@ -75,28 +74,29 @@ anchor: building_and_deploying_your_application * [使用 Jenkins 进行持续集成][Jenkins] * [使用 PHPCI 进行持续集成][PHPCI] +* [使用 PHP Censor 进行持续集成][PHP Censor] * [使用 Teamcity 进行持续集成][Teamcity] -[buildautomation]: http://en.wikipedia.org/wiki/Build_automation -[Phing]: http://www.phing.info/ -[Apache Ant]: http://ant.apache.org/ -[Capistrano]: https://github.com/capistrano/capistrano/wiki -[phpdeploy_capistrano]: http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/ -[phpdeploy_deployer]: http://www.sitepoint.com/deploying-php-applications-with-deployer/ +[buildautomation]: https://wikipedia.org/wiki/Build_automation +[Phing]: https://www.phing.info/ +[Apache Ant]: https://ant.apache.org/ +[Capistrano]: http://capistranorb.com/ +[Ansistrano]: https://ansistrano.com +[phpdeploy_deployer]: https://www.sitepoint.com/deploying-php-applications-with-deployer/ [Chef]: https://www.chef.io/ [chef_vagrant_and_ec2]: http://www.jasongrimes.org/2012/06/managing-lamp-environments-with-chef-vagrant-and-ec2-1-of-3/ [Chef_cookbook]: https://github.com/chef-cookbooks/php [Chef_tutorial]: https://www.youtube.com/playlist?list=PL11cZfNdwNyPnZA9D1MbVqldGuOWqbumZ -[apache_ant_tutorial]: http://net.tutsplus.com/tutorials/other/automate-your-projects-with-apache-ant/ +[apache_ant_tutorial]: https://code.tutsplus.com/tutorials/automate-your-projects-with-apache-ant--net-18595 [Travis CI]: https://travis-ci.org/ -[Jenkins]: http://jenkins-ci.org/ -[PHPCI]: http://www.phptesting.org/ -[Teamcity]: http://www.jetbrains.com/teamcity/ -[Deployer]: http://deployer.org/ +[Jenkins]: https://jenkins.io/ +[PHPCI]: https://www.phptesting.org/ +[PHP Censor]: http://php-censor.info/ +[Teamcity]: https://www.jetbrains.com/teamcity/ +[Deployer]: https://deployer.org/ [Rocketeer]: http://rocketeer.autopergamene.eu/ -[Magallanes]: http://magephp.com/ -[expert_php_deployments]: http://viccherubini.com/assets/Expert-PHP-Deployments.pdf -[deploying_php_applications]: http://www.deployingphpapplications.com +[Magallanes]: https://www.magephp.com/ +[deploying_php_applications]: https://deployingphpapplications.com/ [Ansible]: https://www.ansible.com/ [Puppet]: https://puppet.com/ [ansible_for_devops]: https://leanpub.com/ansible-for-devops diff --git a/_posts/13-02-01-Vagrant.md b/_posts/13-02-01-Vagrant.md index 7f8704158..021c98d92 100644 --- a/_posts/13-02-01-Vagrant.md +++ b/_posts/13-02-01-Vagrant.md @@ -15,15 +15,13 @@ Vagrant 还可以在虚拟机和主机上分享文件夹, 意味着你可以在 下面是一些其他的软件, 可以帮助你更好的使用 Vagrant: -- [Rove][Rove]: 使用 Chef 自动化安装一些常用的软件, PHP 包含在内. - [Puphpet][Puphpet]: 简单的 Web 图形界面用来生成部署 PHP 环境的 Puppet 脚本, 此项目不仅可以用在开发上, 也可以在生产环境中使用. - [Protobox][Protobox]: 是一个基于 vagrant 的一个层, 还有 Web 图形界面, 允许你使用一个 YAML 文件来安装和配置虚拟机里面的软件. - [Phansible][Phansible]: 提供了一个简单的 Web 图形界面, 用来创建 Ansible 自动化部署脚本, 专门为 PHP 项目定制. -[Vagrant]: http://vagrantup.com/ -[Puppet]: http://www.puppetlabs.com/ +[Vagrant]: https://www.vagrantup.com/ +[Puppet]: https://puppet.com/ [Chef]: https://www.chef.io/ -[Rove]: http://rove.io/ [Puphpet]: https://puphpet.com/ -[Protobox]: http://getprotobox.com/ +[Protobox]: https://www.getprotobox.com/ [Phansible]: http://phansible.com/ diff --git a/_posts/13-03-01-Docker.md b/_posts/13-03-01-Docker.md index 930a9ee90..e2e428783 100644 --- a/_posts/13-03-01-Docker.md +++ b/_posts/13-03-01-Docker.md @@ -37,9 +37,9 @@ This will initialize and launch your container. `-d` makes it runs in the backgr * [Docker Hub][docker-hub] * [Docker Hub - official images][docker-hub-official] -[Docker]: http://docker.com/ +[Docker]: https://www.docker.com/ [docker-hub]: https://hub.docker.com/ [docker-hub-official]: https://hub.docker.com/explore/ -[docker-install]: https://docs.docker.com/installation/ -[docker-doc]: https://docs.docker.com/userguide/ +[docker-install]: https://docs.docker.com/install/ +[docker-doc]: https://docs.docker.com/ [PHPDocker.io]: https://phpdocker.io/generator diff --git a/_posts/14-02-01-Opcode-Cache.md b/_posts/14-02-01-Opcode-Cache.md index 45900b381..098db2ef7 100644 --- a/_posts/14-02-01-Opcode-Cache.md +++ b/_posts/14-02-01-Opcode-Cache.md @@ -22,9 +22,10 @@ PHP 5.5 中自带了 opcode 缓存工具,叫做[Zend OPcache][opcache-book], * [WinCache] (extension for MS Windows Server) * [list of PHP accelerators on Wikipedia][PHP_accelerators] -[opcache-book]: http://php.net/book.opcache -[APC]: http://php.net/book.apc -[XCache]: http://xcache.lighttpd.net/ + +[opcache-book]: https://secure.php.net/book.opcache +[APC]: https://secure.php.net/book.apc +[XCache]: https://xcache.lighttpd.net/ [Zend Optimizer+]: https://github.com/zendtech/ZendOptimizerPlus -[WinCache]: http://www.iis.net/download/wincacheforphp -[PHP_accelerators]: http://en.wikipedia.org/wiki/List_of_PHP_accelerators +[WinCache]: https://www.iis.net/downloads/microsoft/wincache-extension +[PHP_accelerators]: https://wikipedia.org/wiki/List_of_PHP_accelerators diff --git a/_posts/14-03-01-Object-Caching.md b/_posts/14-03-01-Object-Caching.md index 0536403cb..6e2e6375c 100644 --- a/_posts/14-03-01-Object-Caching.md +++ b/_posts/14-03-01-Object-Caching.md @@ -35,8 +35,8 @@ print_r($data); ### 更多关于缓存系统的项目: * [APCu](https://github.com/krakjoe/apcu) -* [APC Functions](http://php.net/ref.apc) -* [Memcached](http://memcached.org/) -* [Redis](http://redis.io/) -* [XCache APIs](http://xcache.lighttpd.net/wiki/XcacheApi) -* [WinCache Functions](http://php.net/ref.wincache) +* [APC Functions](https://secure.php.net/ref.apc) +* [Memcached](https://memcached.org/) +* [Redis](https://redis.io/) +* [XCache APIs](https://xcache.lighttpd.net/wiki/XcacheApi) +* [WinCache Functions](https://secure.php.net/ref.wincache) diff --git a/_posts/15-02-01-PHPDoc.md b/_posts/15-02-01-PHPDoc.md index ce052fec0..fd7800f37 100644 --- a/_posts/15-02-01-PHPDoc.md +++ b/_posts/15-02-01-PHPDoc.md @@ -65,10 +65,10 @@ class DateTimeHelper 第二、第三个方法非常类似,和第一个方法一样使用一个 [@param] 标记。第二、和第三个方法之间关键差別在注释区块使用/排除 [@return] 标记。`@return void` 标记明确告诉我们没有返回值,而过去省略 `@return void` 声明也具有相同效果(沒有返回任何值)。 -[标记]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/index.html -[PHPDoc 指南]: http://www.phpdoc.org/docs/latest/index.html -[@author]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/author.html -[@link]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/link.html -[@param]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html -[@return]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/return.html -[@throws]: http://www.phpdoc.org/docs/latest/references/phpdoc/tags/throws.html +[标记]: https://docs.phpdoc.org/references/phpdoc/tags/index.html +[PHPDoc 指南]: https://docs.phpdoc.org/index.html +[@author]: https://docs.phpdoc.org/references/phpdoc/tags/author.html +[@link]: https://docs.phpdoc.org/references/phpdoc/tags/link.html +[@param]: https://docs.phpdoc.org/references/phpdoc/tags/param.html +[@return]: https://docs.phpdoc.org/references/phpdoc/tags/return.html +[@throws]: https://docs.phpdoc.org/references/phpdoc/tags/throws.html diff --git a/_posts/16-02-01-From-the-Source.md b/_posts/16-02-01-From-the-Source.md index 37554c4a7..51cf90349 100644 --- a/_posts/16-02-01-From-the-Source.md +++ b/_posts/16-02-01-From-the-Source.md @@ -6,5 +6,5 @@ anchor: from_the_source ## PHP 官方 {#from_the_source_title} -* [PHP 官方网站](http://php.net/) -* [PHP 官方文档](http://php.net/docs.php) +* [PHP Website](https://secure.php.net/) +* [PHP Documentation](https://secure.php.net/docs.php) diff --git a/_posts/16-03-01-People-to-Follow.md b/_posts/16-03-01-People-to-Follow.md index 196a145ef..87f0bb783 100644 --- a/_posts/16-03-01-People-to-Follow.md +++ b/_posts/16-03-01-People-to-Follow.md @@ -7,13 +7,10 @@ anchor: people_to_follow ## 值得关注的大牛 {#people_to_follow_title} -刚进入社区时很难一下子找到很多有趣或者经验丰富的 PHP 社区成员,你可以在以下链接中找到 PHP 社区成员的 Twitter: +刚进入社区时很难一下子找到很多有趣或者经验丰富的 PHP 社区成员,你可以在以下链接中找到 PHP 社区部分成员名单: -* [New Relic: 25 PHP Developers to Follow Online][php-developers-to-follow] -* [OGProgrammer: How to get connected with the PHP community][og-twitter-list] - -[php-developers-to-follow]: https://blog.newrelic.com/2014/05/02/25-php-developers-follow-online/ -[og-twitter-list]: https://www.ogprogrammer.com/2017/06/28/how-to-get-connected-with-the-php-community/ +* +* diff --git a/_posts/16-04-01-Mentoring.md b/_posts/16-04-01-Mentoring.md index ab85c278f..9ba3dfc72 100644 --- a/_posts/16-04-01-Mentoring.md +++ b/_posts/16-04-01-Mentoring.md @@ -6,4 +6,4 @@ title: 指导 ## 指导 {#mentoring_title} -* [php-mentoring.org](http://php-mentoring.org/) - PHP 社区中的一对一指导。 +* [php-mentoring.org](https://php-mentoring.org/) - PHP 社区中的一对一指导。 diff --git a/_posts/16-05-01-PHP-PaaS-Providers.md b/_posts/16-05-01-PHP-PaaS-Providers.md index 52c3062c0..ba5d120ae 100644 --- a/_posts/16-05-01-PHP-PaaS-Providers.md +++ b/_posts/16-05-01-PHP-PaaS-Providers.md @@ -6,19 +6,19 @@ anchor: php_paas_providers ## PHP 的 Paas 提供商 {#php_paas_providers_title} -* [PagodaBox](https://pagodabox.io/) * [AppFog](https://www.ctl.io/appfog/) -* [Heroku](https://devcenter.heroku.com/categories/php) -* [fortrabbit](https://www.fortrabbit.com/) -* [Engine Yard Cloud](https://www.engineyard.com/features) -* [Red Hat OpenShift Platform](https://www.openshift.com/) * [AWS Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/) -* [Windows Azure](http://www.windowsazure.com/) +* [Cloudways](https://www.cloudways.com/) +* [Engine Yard Cloud](https://www.engineyard.com/features) +* [fortrabbit](https://www.fortrabbit.com/) * [Google App Engine](https://cloud.google.com/appengine/docs/php/) -* [Jelastic](http://jelastic.com/) +* [Heroku](https://devcenter.heroku.com/categories/php-support) +* [IBM Cloud](https://console.bluemix.net/docs/runtimes/php/getting-started.html#getting_started) +* [Jelastic](https://jelastic.com/) +* [Microsoft Azure](https://azure.microsoft.com/) +* [Nanobox](https://nanobox.io/) +* [Pivotal Web Services](https://run.pivotal.io/) * [Platform.sh](https://platform.sh/) -* [Cloudways](https://www.cloudways.com/en/) -* [IBM Bluemix Cloud Foundry](https://console.ng.bluemix.net/) -* [Pivotal Web Service Cloud Foundry](https://run.pivotal.io/) +* [Red Hat OpenShift](https://www.openshift.com/) To see which versions these PaaS hosts are running, head over to [PHP Versions](http://phpversions.info/paas-hosting/). diff --git a/_posts/16-06-01-Frameworks.md b/_posts/16-06-01-Frameworks.md index 1ec829de2..c9ed9dd06 100644 --- a/_posts/16-06-01-Frameworks.md +++ b/_posts/16-06-01-Frameworks.md @@ -18,6 +18,4 @@ title: 框架 许多的框架会在微型框架上加入相当多的功能,我们则称之为全栈框架。这些框架通常会提供 ORMs ,身份认证扩展包等等。 -组件框架是多个独立的类库所结合起来的。不同的组件框架可以一起使用在微型或是全栈框架上。 - -* [热门的 PHP 框架](https://github.com/codeguy/php-the-right-way/wiki/Frameworks) \ No newline at end of file +组件框架是多个独立的类库所结合起来的。不同的组件框架可以一起使用在微型或是全栈框架上。 \ No newline at end of file diff --git a/_posts/16-07-01-Components.md b/_posts/16-07-01-Components.md index 11055c31a..eae4918e4 100644 --- a/_posts/16-07-01-Components.md +++ b/_posts/16-07-01-Components.md @@ -19,9 +19,15 @@ title: 组件 例如,你可以使用 [FuelPHP 验证类库],而不使用 FuelPHP 整个框架。 * [Aura] +* CakePHP Components + * [Collection] + * [Database] + * [Datasource] + * [Event] + * [I18n] + * [ORM] * [FuelPHP] * [Hoa Project] -* [Orno] * [Symfony Components] * [The League of Extraordinary Packages] * Laravel's Illuminate Components @@ -35,23 +41,25 @@ _Laravel 的 [Illuminate 组件] 和 Laravel 框架将变得更加解耦。 现 [PEAR]: /#pear [Dependency Management]: /#dependency_management [FuelPHP Validation package]: https://github.com/fuelphp/validation -[Aura]: http://auraphp.com/framework/2.x/en/ +[Aura]: http://auraphp.com/framework/ [FuelPHP]: https://github.com/fuelphp [Hoa Project]: https://github.com/hoaproject -[Orno]: https://github.com/orno -[Symfony Components]: http://symfony.com/doc/current/components/index.html -[The League of Extraordinary Packages]: http://thephpleague.com/ +[Symfony Components]: https://symfony.com/doc/current/components/index.html +[The League of Extraordinary Packages]: https://thephpleague.com/ [IoC Container]: https://github.com/illuminate/container [Eloquent ORM]: https://github.com/illuminate/database [Queue]: https://github.com/illuminate/queue [Illuminate components]: https://github.com/illuminate +[Collection]: https://github.com/cakephp/collection +[Database]: https://github.com/cakephp/database +[Datasource]: https://github.com/cakephp/datasource +[Event]: https://github.com/cakephp/event +[I18n]: https://github.com/cakephp/i18n +[ORM]: https://github.com/cakephp/orm Laravel 中文资料: -- [Laravel 中文书籍《Laravel 入门教程》](https://laravel-china.org/topics/3383) -- [下载量最高的 100 个 Laravel 扩展包推荐 ](https://laravel-china.org/topics/2530) -- [Laravel 中文文档,涵盖 5.1, 5.2, 5.3 版本](https://laravel-china.org/docs/home ) -- [Laravel 招聘 ](https://laravel-china.org/categories/1) -- [Laravel 远程工作](https://laravel-china.org/topics/3626) -- [Laravel 中文社区](https://laravel-china.org/) 我们是现代化 PHP 的拥护者 +- [Laravel 中文书籍《Laravel 入门教程》](https://learnku.com/topics/3383) +- [Laravel 中文文档,涵盖 5.1~5.8 版本](https://learnku.com/docs/laravel/5.8) +- [Laravel 中文社区](https://learnku.com/) 我们是现代化 PHP 的拥护者 - [Laravel 速查表](https://cs.laravel-china.org/) \ No newline at end of file diff --git a/_posts/16-08-01-Sites.md b/_posts/16-08-01-Sites.md index c8057cdd2..f9fecb00b 100644 --- a/_posts/16-08-01-Sites.md +++ b/_posts/16-08-01-Sites.md @@ -10,35 +10,33 @@ title: 其他有用的资源 * [PHP Cheatsheets](http://phpcheatsheets.com/) - for variable comparisons, arithmetics and variable testing in various PHP versions -* [PHP Security Cheatsheet](https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet) +* [OWASP Security Cheatsheets](https://www.owasp.org/index.php/OWASP_Cheat_Sheet_Series) - provides a concise collection of high value information on specific application security topics. ### 更多最佳实践 * [PHP Best Practices](https://phpbestpractices.org/) * [Best practices for Modern PHP Development](https://www.airpair.com/php/posts/best-practices-for-modern-php-development) +* [Why You Should Be Using Supported PHP Versions](https://kinsta.com/blog/php-versions/) ### PHP Web 开发社区的新人 你可以通过订阅周刊资讯来获取关于扩展包推荐、最新消息、特殊事件或者是社区公告,还有不定时发布的资源: * [PHP Weekly](http://www.phpweekly.com) -* [JavaScript Weekly](http://javascriptweekly.com) -* [HTML5 Weekly](http://html5weekly.com) -* [Mobile Web Weekly](http://mobilewebweekly.co) -* There are also Weeklies on other platforms you might be interested in; here's -[a list of some](https://github.com/jondot/awesome-weekly). +* [JavaScript Weekly](https://javascriptweekly.com/) +* [Frontend Focus](https://frontendfoc.us/) +* [Mobile Web Weekly](https://mobiledevweekly.com/) + +您可能对其他平台的《周刊》也有兴趣; 这是[一些清单](https://github.com/jondot/awesome-weekly). ### PHP 世界 -* [PHP Developer blog](http://blog.phpdeveloper.org/) +* [PHP Developer blog](https://blog.phpdeveloper.org/) ## Laravel 中文资料 -- [Laravel 中文书籍《Laravel 入门教程》](https://laravel-china.org/topics/3383) -- [下载量最高的 100 个 Laravel 扩展包推荐 ](https://laravel-china.org/topics/2530) -- [Laravel 中文文档,涵盖 5.1, 5.2, 5.3 版本](https://laravel-china.org/docs/home ) -- [Laravel 招聘 ](https://laravel-china.org/categories/1) -- [Laravel 远程工作](https://laravel-china.org/topics/3626) -- [Laravel 中文社区](https://laravel-china.org/) 我们是现代化 PHP 的拥护者 +- [Laravel 中文书籍《Laravel 入门教程》](https://learnku.com/topics/3383) +- [Laravel 中文文档,涵盖 5.1~5.8 版本](https://learnku.com/docs/laravel/5.8) +- [Laravel 中文社区](https://learnku.com/) 我们是现代化 PHP 的拥护者 - [Laravel 速查表](https://cs.laravel-china.org/) diff --git a/_posts/16-09-01-Videos.md b/_posts/16-09-01-Videos.md index f7eac39bd..9cc6da5a9 100644 --- a/_posts/16-09-01-Videos.md +++ b/_posts/16-09-01-Videos.md @@ -13,8 +13,8 @@ title: 视频教程 ### 付费视频 -* [Standards and Best practices](http://teamtreehouse.com/library/standards-and-best-practices) -* [PHP Training on Pluralsight](http://www.pluralsight.com/search/?searchTerm=php) -* [PHP Training on Lynda.com](http://www.lynda.com/search?q=php) -* [PHP Training on Tutsplus](http://code.tutsplus.com/categories/php/courses) -* [Laracasts](https://laracasts.com/) +* [Standards and Best practices](https://teamtreehouse.com/library/php-standards-and-best-practices) +* [PHP Training on Pluralsight](https://www.pluralsight.com/search?q=php) +* [PHP Training on Lynda.com](https://www.lynda.com/search?q=php) +* [PHP Training on Tutsplus](https://code.tutsplus.com/categories/php/courses) +* [Laracasts](https://laracasts.com/) \ No newline at end of file diff --git a/_posts/16-10-01-Books.md b/_posts/16-10-01-Books.md index bbd15bda5..786759124 100644 --- a/_posts/16-10-01-Books.md +++ b/_posts/16-10-01-Books.md @@ -18,14 +18,18 @@ title: 书籍 ### 付费书籍 -* [Laravel 中文书籍《Laravel 入门教程》](https://laravel-china.org/topics/3383) - Web 开发实战书籍,一步步构建一个微博应用 -* [Build APIs You Won't Hate](https://apisyouwonthate.com/) - 教你构建 API -* [Modern PHP](http://shop.oreilly.com/product/0636920033868.do) - 现代化 PHP -* [Building Secure PHP Apps](https://leanpub.com/buildingsecurephpapps) - 构建安全的 PHP 应用 -* [Modernizing Legacy Applications In PHP](https://leanpub.com/mlaphp) - 小步迭代的升级你的 PHP 项目 -* [Securing PHP: Core Concepts](https://leanpub.com/securingphp-coreconcepts) - PHP 安全核心概念 -* [Scaling PHP](http://www.scalingphpbook.com/) - 高可用性 PHP -* [Signaling PHP](https://leanpub.com/signalingphp) - PHP 命令行实战 -* [The Grumpy Programmer's Guide To Building Testable PHP Applications](https://leanpub.com/grumpy-testing) - PHP 测试指南 -* [Minimum Viable Tests](https://leanpub.com/minimumviabletests) - 小步迭代开始学习 PHP 测试 -* [Domain-Driven Design in PHP](https://leanpub.com/ddd-in-php) - PHP 的 DDD 设计模式详解 +* [Laravel 中文书籍《Laravel 入门教程》](https://learnku.com/laravel/t/3383/laravel-the-first-chinese-new-book-laravel-tutorial) - Web 开发实战书籍,一步步构建一个微博应用 +* [Build APIs You Won't Hate](https://apisyouwonthate.com/) - Everyone and their dog wants an API, +so you should probably learn how to build them. +* [Modern PHP](http://shop.oreilly.com/product/0636920033868.do) - covers modern PHP features, best practices, testing, tuning, deployment and setting up a dev environment. +* [Building Secure PHP Apps](https://leanpub.com/buildingsecurephpapps) - Learn the security basics that a senior +developer usually acquires over years of experience, all condensed down into one quick and easy handbook +* [Modernizing Legacy Applications In PHP](https://leanpub.com/mlaphp) - Get your code under control in a series of +small, specific steps +* [Securing PHP: Core Concepts](https://leanpub.com/securingphp-coreconcepts) - A guide to some of the most common +security terms and provides some examples of them in every day PHP +* [Scaling PHP](http://www.scalingphpbook.com/) - Stop playing sysadmin and get back to coding +* [Signaling PHP](https://leanpub.com/signalingphp) - PCNLT signals are a great help when writing PHP scripts that +run from the command line. +* [Minimum Viable Tests](https://leanpub.com/minimumviabletests) - Long-time PHP testing evangelist Chris Hartjes goes over what he feels is the minimum you need to know to get started. +* [Domain-Driven Design in PHP](https://leanpub.com/ddd-in-php) - See real examples written in PHP showcasing Domain-Driven Design Architectural Styles (Hexagonal Architecture, CQRS or Event Sourcing), Tactical Design Patterns, and Bounded Context Integration. diff --git a/_posts/17-01-01-Community.md b/_posts/17-01-01-Community.md index 2a5f8f007..8c8ce5bad 100644 --- a/_posts/17-01-01-Community.md +++ b/_posts/17-01-01-Community.md @@ -5,14 +5,14 @@ title: 社区 # 社区 {#community_title} -PHP 社区多元化并且规模庞大,成员们也乐意并随时准备好帮助新人。你可以考虑加入当地的 PHP 使用者社区 (PUG) 或者参加教大型的 PHP 会议,从中学习更多最佳实践。你也可以使用 IRC 逛逛 [irc.freenode.com][php-irc] 上的 #phpc 频道,也可以关注 [@phpc][phpc-twitter] 的Twitter 账号。试着去多结交一些新的开发者,学习新的东西,总之,交一些新朋友!其他的社区资源包含 Google+ 的 PHP [Programmer community][php-programmers-gplus] 以及 [StackOverflow][php-so]。 +PHP 社区多元化并且规模庞大,成员们也乐意并随时准备好帮助新人。你可以考虑加入当地的 PHP 使用者社区 (PUG) 或者参加教大型的 PHP 会议,从中学习更多最佳实践。你也可以使用 IRC 逛逛 [irc.freenode.com][php-irc] 上的 #phpc 频道,也可以关注 [@phpc][phpc-twitter] 的Twitter 账号。试着去多结交一些新的开发者,学习新的东西,总之,交一些新朋友!其他的社区资源包含[StackOverflow][php-so]。 -中文的 PHP 开发者,欢迎加入 [Laravel China 社区](https://laravel-china.org/) (简称 LC)。LC 是 PHP 和 Laravel 开发者社区,致力于为 PHP 和 Laravel 开发者提供一个分享创造、结识伙伴、协同互助的平台。LC 是现代化 PHP 的拥护者。LC 也是这个 PHP The Right Way 中文文档的维护者。 +中文的 PHP 开发者,欢迎加入 [LearnKu 社区](https://learnku.com/php)。LearnKu 是终身学习者的编程知识社区。 [阅读 PHP 官方事件日历][php-calendar] -[php-irc]: http://webchat.freenode.net/?channels=phpc +[php-irc]: https://webchat.freenode.net/?channels=phpc [phpc-twitter]: https://twitter.com/phpc [php-programmers-gplus]: https://plus.google.com/u/0/communities/104245651975268426012 -[php-so]: http://stackoverflow.com/questions/tagged/php -[php-calendar]: http://php.net/cal.php +[php-so]: https://stackoverflow.com/questions/tagged/php +[php-calendar]: https://secure.php.net/cal.php diff --git a/_posts/17-02-01-User-Groups.md b/_posts/17-02-01-User-Groups.md index 7bf9235ef..41af86137 100644 --- a/_posts/17-02-01-User-Groups.md +++ b/_posts/17-02-01-User-Groups.md @@ -6,7 +6,7 @@ title: 用户群 ## PHP 用户群 {#user_groups_title} -如果你住在较大的城市,附近应该就有 PHP 用户群。你可以通过基于 [PHP.ug][php-ug] 的 [usergroup-list at php.net][php-uglist] 这个地址找到当地的 PUG。也可以通过 [Meetup.com][meetup] 或者使用搜索引擎 (i.e. [Google][google]) 搜索 ```php user group near me``` 。如果你住在比较小的城镇,当地也许还没有 PUG ,如果是这种情形,不妨就开始组建一个。 +如果你住在较大的城市,附近应该就有 PHP 用户群。您可以在 [PHP.ug][php-ug] 轻松地找到本地PUG。也可以通过 [Meetup.com][meetup] 或者使用搜索引擎 (i.e. [Google][google]) 搜索 ```php user group near me``` 。如果你住在比较小的城镇,当地也许还没有 PUG ,如果是这种情形,不妨就开始组建一个。 这里要特别提到两个全球的用户组:[NomadPHP] 和 [PHPWomen]。[NomadPHP] 提供每月两次的在线用户组会议,由 PHP 社区里顶尖的高手进行演讲。[PHPWomen] 原本是针对女性 PHP 开发者的非排他性的用户组。会员资格发放给那些支持多元化社区的人。PHPWomen 提供了一技术支持,指导和教育的个平台,并且促进了女性的创造力以及专业的氛围。 @@ -14,8 +14,7 @@ title: 用户群 [google]: https://www.google.com/search?q=php+user+group+near+me [meetup]: http://www.meetup.com/find/ -[php-ug]: http://php.ug/ +[php-ug]: https://php.ug/ [NomadPHP]: https://nomadphp.com/ [PHPWomen]: http://phpwomen.org/ [php-wiki]: https://wiki.php.net/usergroups -[php-uglist]: http://php.net/ug.php diff --git a/_posts/17-03-01-Conferences.md b/_posts/17-03-01-Conferences.md index 18e07703f..cff181f90 100644 --- a/_posts/17-03-01-Conferences.md +++ b/_posts/17-03-01-Conferences.md @@ -10,4 +10,4 @@ title: PHP 大会 [查找 PHP 会议][php-conf] -[php-conf]: http://php.net/conferences/index.php +[php-conf]: https://secure.php.net/conferences/index.php diff --git a/_posts/17-04-01-Elephpants.md b/_posts/17-04-01-Elephpants.md index c38883393..8e6bad2af 100644 --- a/_posts/17-04-01-Elephpants.md +++ b/_posts/17-04-01-Elephpants.md @@ -10,6 +10,7 @@ anchor: elephpants [Interview with Vincent Pontier][vincent-pontier-interview] -[elephpant]: http://php.net/elephpant.php -[vincent-pontier-interview]: http://7php.com/elephpant/ +[elephpant]: https://secure.php.net/elephpant.php +[vincent-pontier-interview]: https://7php.com/elephpant/ [vincent-pontier]: http://www.elroubio.net/ + diff --git a/pages/Design-Patterns.md b/pages/Design-Patterns.md index 4faf1c3ef..95f6dd3b7 100644 --- a/pages/Design-Patterns.md +++ b/pages/Design-Patterns.md @@ -172,7 +172,7 @@ $data = $client->loadOutput(); ## 模型-视图-控制器(MVC) -模型-视图-控制器 (MVC) 模式还有和它相关的 HMVC、HVVM 让你根据逻辑对象的不同作用去解耦。 +模型-视图-控制器 (MVC) 模式还有和它相关的 HMVC、MVVM 让你根据逻辑对象的不同作用去解耦。 模型用来作为数据访问层,并以应用中通用的格式返回数据。 控制器处理请求,处理从模型层返回的数据,并载入视图,发送响应。 视图用来展示需要在响应中使用的模板(markup, xml 等等)。 diff --git a/pages/Functional-Programming.md b/pages/Functional-Programming.md index 85bb97f2a..795027a8f 100644 --- a/pages/Functional-Programming.md +++ b/pages/Functional-Programming.md @@ -76,7 +76,7 @@ Each filter function in the family accepts only elements greater than some minim `criteria_greater_than` is called). Early binding is used by default for importing `$min` variable into the created function. For true closures with late -binding one should use a reference when importing. Imagine a templating or input validation library, where closure is +binding one should use a reference when importing. Imagine a templating or input validation library, where a closure is defined to capture variables in scope and access them later when the anonymous function is evaluated. * [Read about Anonymous functions][anonymous-functions] diff --git a/pages/The-Basics.md b/pages/The-Basics.md index b13ceb23d..64099a4ae 100644 --- a/pages/The-Basics.md +++ b/pages/The-Basics.md @@ -4,12 +4,11 @@ title: The Basics sitemap: true --- -# The Basics +# 基础 -## Comparison operators +## 比较运算符 -Comparison operators are an often overlooked aspect of PHP, which can lead to many unexpected outcomes. One such -problem stems from strict comparisons (the comparison of booleans as integers). +比较运算符在PHP中经常容易被忽略,但是它常常会导致一些意想不到的输出结果。下面是一个常见的例子,在使用比较运算符,比较整型变量和布尔值。 {% highlight php %} 应该注意的是,多行字符串也可以通过在语句中跨多行继续来形成。 _例如_ + +{% highlight php %} +$str = " +Example of string +spanning multiple lines +using statement syntax. +$a are parsed. +"; + +/** + * 输出: + * + * 字符串示例 + * 跨越多行 + * 使用语句语法。 + * $a 被解析。 + */ +{% endhighlight %} + +### 哪一种更快? + +这里有一种谣言就是单引号会比双引号在使用上稍快一些,实际上这并不是真是的。 -There is a myth floating around that single quote strings are fractionally quicker than double quote strings. This is -fundamentally not true. +如果你定义了一个简单字符串,没有使用任何复杂变量和特殊字符串,使用单引号和双引号的效果是相同的,两者并不会谁更快。 -If you are defining a single string and not trying to concatenate values or anything complicated, then either a single -or double quoted string will be entirely identical. Neither are quicker. -If you are concatenating multiple strings of any type, or interpolate values into a double quoted string, then the -results can vary. If you are working with a small number of values, concatenation is minutely faster. With a lot of -values, interpolating is minutely faster. +如果要连接任意类型的多个字符串,或在双引号字符串中进行插值,则结果可能会有所不同。如果您使用的是少量的值,那么进行连接速度会稍微快一点。对于大量的值,进行插值操作速度要快得多。 -Regardless of what you are doing with strings, none of the types will ever have any noticeable impact on your -application. Trying to rewrite code to use one or the other is always an exercise in futility, so avoid this micro- -optimization unless you really understand the meaning and impact of the differences. +无论你使用字符串做什么,这些类型都不会对你的应用产生任何明显的影响。尝试重写代码以使用其他方式是徒劳,所以请避免过度优化,除非您真正了解差异的含义和影响。 -* [Disproving the Single Quotes Performance Myth](http://nikic.github.io/2012/01/09/Disproving-the-Single-Quotes-Performance-Myth.html) +* [驳斥单引号的性能谣言](http://nikic.github.io/2012/01/09/Disproving-the-Single-Quotes-Performance-Myth.html) -## Ternary operators +## 三元运算符 -Ternary operators are a great way to condense code, but are often used in excess. While ternary operators can be -stacked/nested, it is advised to use one per line for readability. +三元运算符是精简代码的好方法,但也往往存在着过度使用.当三元运算符可堆叠/嵌套时,建议保持每一行的可读性。 {% highlight php %}