From 7a770e3fbed85c8fb446a1ccc41d657242382a99 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 28 Mar 2019 18:12:21 +0800 Subject: [PATCH 01/16] update --- _includes/welcome.md | 2 +- ...01-02-01-Use-the-Current-Stable-Version.md | 6 +- _posts/01-04-01-Mac-Setup.md | 13 +- _posts/01-06-01-Common-Directory-structure.md | 19 ++ _posts/02-01-01-Code-Style-Guide.md | 26 +-- _posts/03-02-01-Programming-Paradigms.md | 19 +- _posts/03-03-01-Namespaces.md | 7 +- _posts/03-04-01-Standard-PHP-Library.md | 5 +- _posts/03-05-01-Command-Line-Interface.md | 16 +- _posts/03-06-01-XDebug.md | 7 +- _posts/04-02-01-Composer-and-Packagist.md | 52 ++--- _posts/04-03-01-PEAR.md | 10 +- _posts/05-02-01-The-Basics.md | 2 +- _posts/05-03-01-Date-and-Time.md | 6 +- _posts/05-04-01-Design-Patterns.md | 2 +- _posts/05-05-01-PHP-and-UTF8.md | 71 ++++--- ...1-Internationalization-and-Localization.md | 186 +++++++++--------- _posts/06-01-01-Dependency-Injection.md | 2 +- _posts/06-03-01-Complex-Problem.md | 52 +++++ _posts/06-05-01-Further-Reading.md | 4 +- _posts/07-01-01-Databases.md | 6 +- _posts/07-02-01-Databases_MySQL.md | 20 +- _posts/07-03-01-Databases_PDO.md | 6 +- _posts/07-04-01-Interacting-via-Code.md | 6 +- _posts/07-05-01-Abstraction-Layers.md | 8 +- _posts/08-04-01-Compiled-Templates.md | 6 +- _posts/08-05-01-Further-Reading.md | 18 +- _posts/09-02-01-Errors.md | 19 +- _posts/09-03-01-Exceptions.md | 6 +- _posts/10-01-01-Security.md | 3 + _posts/10-02-01-Web-Application-Security.md | 32 ++- _posts/10-03-01-Password-Hashing.md | 29 ++- _posts/10-04-01-Data-Filtering.md | 14 +- _posts/10-06-01-Register-Globals.md | 2 +- _posts/10-07-01-Error-Reporting.md | 8 +- _posts/11-02-01-Test-Driven-Development.md | 14 +- .../11-03-01-Behavior-Driven-Development.md | 8 +- .../11-04-01-Complementary-Testing-Tools.md | 11 +- .../12-03-01-Virtual-or-Dedicated-Servers.md | 18 +- _posts/12-05-01-Building-your-Application.md | 28 +-- _posts/13-02-01-Vagrant.md | 6 +- _posts/13-03-01-Docker.md | 6 +- _posts/14-02-01-Opcode-Cache.md | 11 +- _posts/14-03-01-Object-Caching.md | 10 +- _posts/15-02-01-PHPDoc.md | 14 +- _posts/16-02-01-From-the-Source.md | 4 +- _posts/16-03-01-People-to-Follow.md | 9 +- _posts/16-04-01-Mentoring.md | 2 +- _posts/16-05-01-PHP-PaaS-Providers.md | 20 +- _posts/16-06-01-Frameworks.md | 4 +- _posts/16-07-01-Components.md | 30 +-- _posts/16-08-01-Sites.md | 22 +-- _posts/16-09-01-Videos.md | 10 +- _posts/16-10-01-Books.md | 26 +-- _posts/17-01-01-Community.md | 8 +- _posts/17-02-01-User-Groups.md | 3 +- _posts/17-03-01-Conferences.md | 2 +- _posts/17-04-01-Elephpants.md | 5 +- 58 files changed, 550 insertions(+), 411 deletions(-) create mode 100644 _posts/01-06-01-Common-Directory-structure.md diff --git a/_includes/welcome.md b/_includes/welcome.md index 6257fbaf0..c75b55e3e 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -49,5 +49,5 @@ _PHP: 您可以在网站上放置 PHP之道 的横幅来支持我们,让 PHP [广告横幅][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 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..c738bcfe2 100644 --- a/_posts/01-02-01-Use-the-Current-Stable-Version.md +++ b/_posts/01-02-01-Use-the-Current-Stable-Version.md @@ -1,12 +1,12 @@ --- -title: 使用当前稳定版本 (7.1) +title: 使用当前稳定版本 (7.2) isChild: true anchor: use_the_current_stable_version --- -## 使用当前稳定版本 (7.1) {#use_the_current_stable_version_title} +## 使用当前稳定版本 (7.2) {#use_the_current_stable_version_title} -如果你刚开始学习 PHP,请使用最新的稳定版本 [PHP 7.1][php-release]。PHP 7.1 非常新,相较于 5.x 版本增加了强大的 [新特性](#language_highlights)。PHP 引擎大部分被重写,PHP 的运行速度已经远远超越过去。 +如果你刚开始学习 PHP,请使用最新的稳定版本 [PHP 7.2][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] 中查找。 diff --git a/_posts/01-04-01-Mac-Setup.md b/_posts/01-04-01-Mac-Setup.md index 512bc60c1..39462ab41 100644 --- a/_posts/01-04-01-Mac-Setup.md +++ b/_posts/01-04-01-Mac-Setup.md @@ -6,28 +6,27 @@ 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`,并且通过修改 `PATH` 变量来切换各个版本。或者你也可以使用 [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`,比如: sudo port install php56 sudo port install php71 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..eed57ce48 --- /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包和框架目录标准对项目的发展是非常有意义的。 + +[Paul M. Jones]: https://twitter.com/pmjones +[Standard PHP Package Skeleton]: https://github.com/php-pds/skeleton +[Composer]: /#composer_and_packagist diff --git a/_posts/02-01-01-Code-Style-Guide.md b/_posts/02-01-01-Code-Style-Guide.md index 3768f4a52..0b2b566b8 100644 --- a/_posts/02-01-01-Code-Style-Guide.md +++ b/_posts/02-01-01-Code-Style-Guide.md @@ -7,11 +7,10 @@ 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-2][psr2] 和 [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-4][psr4] @@ -42,14 +41,19 @@ PHP 社区百花齐放,拥有大量的函数库、框架和组件。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/ +[psr2]: https://www.php-fig.org/psr/psr-2/ +[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..b28ce7cf7 100644 --- a/_posts/03-05-01-Command-Line-Interface.md +++ b/_posts/03-05-01-Command-Line-Interface.md @@ -47,12 +47,10 @@ 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..962399c35 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/ +[Packagist]: https://packagist.org/ +[Twig]: https://twig.symfony.com/ +[libraries.io]: https://libraries.io/ [Security Advisories Checker]: https://security.sensiolabs.org/ -[Learn about Composer]: http://getcomposer.org/doc/00-intro.md +[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..9b1714732 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://php.net/book.datetime +[dateformat]: https://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..8a4793e83 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://php.net/book.mbstring [patchwork/utf8]: https://packagist.org/packages/patchwork/utf8 ### 数据库层面的 UTF-8 @@ -43,12 +43,17 @@ _本章是由 [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 进行编码的。以前这一步是通过在页面 `` 标签下包含[字符集 `` 标签](https://htmlpurifier.org/docs/enduser-utf8.html)实现的,这是一种可行的方式。但更好的做法是在 `Content-Type` 响应头中进行设置,因为这样做的速度会[更快](https://developers.google.com/speed/docs/best-practices/rendering#SpecifyCharsetEarly)。 {% highlight php %} prepare('insert into ElvishSentences (Id, Body) values (?, ?)'); -$handle->bindValue(1, 1, PDO::PARAM_INT); -$handle->bindValue(2, $string); +$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); // explicitly tell pdo to expect an 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 +// 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'); +// An example wrapper to allow you to escape data to html +function escape_to_html($dirty){ + echo htmlspecialchars($dirty, ENT_QUOTES, 'UTF-8'); +} + +header('Content-Type: text/html; charset=UTF-8'); // Unnecessary if your default_charset is set to utf-8 already ?> @@ -98,7 +111,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); // This should correctly output our transformed UTF-8 string to the browser } ?> @@ -107,23 +120,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..769268d67 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-2.0/guide-tutorial-i18n.html +[intl]: https://br2.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..cfd067d4a 100644 --- a/_posts/06-03-01-Complex-Problem.md +++ b/_posts/06-03-01-Complex-Problem.md @@ -20,6 +20,58 @@ title: 复杂的问题 依赖反转准则是面向对象设计准则 S.O.L.I.D 中的 "D" ,倡导 *"依赖于抽象而不是具体"*。简单来说就是依赖应该是接口/约定或者抽象类,而不是具体的实现。我们能很容易重构前面的例子,使之遵循这个准则 +#### Single Responsibility Principle + +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. + +#### Liskov Substitution Principle + +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. + +#### Interface Segregation Principle + +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. + +#### Dependency Inversion Principle + +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(); * [了解 PDO 连接] -[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 +[了解 PDO]: https://secure.php.net/book.pdo +[了解 PDO 连接]: 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..c49c1839a 100644 --- a/_posts/07-04-01-Interacting-via-Code.md +++ b/_posts/07-04-01-Interacting-via-Code.md @@ -90,6 +90,6 @@ class FooModel [PHPBridge] 具有一项非常棒的资源叫做[创建一个数据类]。它包含了非常相似的逻辑而且非常适合刚刚习惯数据库交互概念的开发者使用。 -[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/ +[创建一个数据类]: 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..3cac544e0 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..9563afd2d 100644 --- a/_posts/12-05-01-Building-your-Application.md +++ b/_posts/12-05-01-Building-your-Application.md @@ -77,26 +77,26 @@ anchor: building_and_deploying_your_application * [使用 PHPCI 进行持续集成][PHPCI] * [使用 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..fa5cb3caf 100644 --- a/_posts/13-02-01-Vagrant.md +++ b/_posts/13-02-01-Vagrant.md @@ -20,10 +20,10 @@ Vagrant 还可以在虚拟机和主机上分享文件夹, 意味着你可以在 - [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..ce1307765 100644 --- a/_posts/16-08-01-Sites.md +++ b/_posts/16-08-01-Sites.md @@ -10,35 +10,31 @@ 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/) ### 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..a60e413d0 100644 --- a/_posts/17-01-01-Community.md +++ b/_posts/17-01-01-Community.md @@ -7,12 +7,12 @@ 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 开发者,欢迎加入 [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..856d6020f 100644 --- a/_posts/17-02-01-User-Groups.md +++ b/_posts/17-02-01-User-Groups.md @@ -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/ + From 0638660114db9ac3ce5f4cc5a597441e96ce3bec Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 1 Apr 2019 17:18:07 +0800 Subject: [PATCH 02/16] updtae jekyll --- Gemfile.lock | 113 ++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 50 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index da1149421..d0b2ae141 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,57 +2,62 @@ GEM remote: https://rubygems.org/ specs: RedCloth (4.2.9) - activesupport (5.0.0.1) + activesupport (5.2.3) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (~> 0.7) + i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) addressable (2.4.0) blankslate (2.1.2.4) - classifier-reborn (2.0.4) + classifier-reborn (2.2.0) fast-stemmer (~> 1.0) coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.10.0) + coffee-script-source (1.12.2) colorator (0.1) - concurrent-ruby (1.0.2) - ethon (0.9.1) + concurrent-ruby (1.1.5) + ethon (0.12.0) ffi (>= 1.3.0) execjs (2.7.0) - faraday (0.10.0) + faraday (0.15.4) multipart-post (>= 1.2, < 3) fast-stemmer (1.0.2) - ffi (1.9.14) - ffi (1.9.14-x64-mingw32) + ffi (1.10.0) + ffi (1.10.0-x64-mingw32) gemoji (2.1.0) - github-pages (39) + github-pages (43) RedCloth (= 4.2.9) - github-pages-health-check (~> 0.2) + github-pages-health-check (= 0.6.0) jekyll (= 2.4.0) jekyll-coffeescript (= 1.0.1) jekyll-feed (= 0.3.1) + jekyll-gist (= 1.4.0) jekyll-mentions (= 0.2.1) - jekyll-redirect-from (= 0.8.0) + jekyll-paginate (= 1.1.0) + jekyll-redirect-from (= 0.9.1) jekyll-sass-converter (= 1.3.0) - jekyll-sitemap (= 0.8.1) + jekyll-seo-tag (= 0.1.4) + jekyll-sitemap (= 0.9.0) jemoji (= 0.5.0) - kramdown (= 1.5.0) + kramdown (= 1.9.0) liquid (= 2.6.2) maruku (= 0.7.0) mercenary (~> 0.3) pygments.rb (= 0.6.3) - rdiscount (= 2.1.7) - redcarpet (= 3.3.2) + rdiscount (= 2.1.8) + redcarpet (= 3.3.3) terminal-table (~> 1.4) - github-pages-health-check (0.3.2) - net-dns (~> 0.6) + github-pages-health-check (0.6.0) + addressable (~> 2.3) + net-dns (~> 0.8) public_suffix (~> 1.4) typhoeus (~> 0.7) - html-pipeline (1.9.0) + html-pipeline (1.11.0) activesupport (>= 2) nokogiri (~> 1.4) - i18n (0.7.0) + i18n (1.6.0) + concurrent-ruby (~> 1.0) jekyll (2.4.0) classifier-reborn (~> 2.0) colorator (~> 0.1) @@ -77,63 +82,71 @@ GEM html-pipeline (~> 1.9.0) jekyll (~> 2.0) jekyll-paginate (1.1.0) - jekyll-redirect-from (0.8.0) + jekyll-redirect-from (0.9.1) jekyll (>= 2.0) jekyll-sass-converter (1.3.0) sass (~> 3.2) - jekyll-sitemap (0.8.1) - jekyll-watch (1.5.0) - listen (~> 3.0, < 3.1) + jekyll-seo-tag (0.1.4) + jekyll (>= 2.0) + jekyll-sitemap (0.9.0) + jekyll-watch (1.5.1) + listen (~> 3.0) jemoji (0.5.0) gemoji (~> 2.0) html-pipeline (~> 1.9) jekyll (>= 2.0) - kramdown (1.5.0) + kramdown (1.9.0) liquid (2.6.2) - listen (3.0.8) + listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) maruku (0.7.0) mercenary (0.3.6) - mini_portile2 (2.1.0) - minitest (5.9.1) + mini_portile2 (2.4.0) + minitest (5.11.3) multipart-post (2.0.0) - net-dns (0.8.0) - nokogiri (1.6.8.1) - mini_portile2 (~> 2.1.0) - nokogiri (1.6.8.1-x64-mingw32) - mini_portile2 (~> 2.1.0) - octokit (4.6.1) + net-dns (0.9.0) + nokogiri (1.10.2) + mini_portile2 (~> 2.4.0) + nokogiri (1.10.2-x64-mingw32) + mini_portile2 (~> 2.4.0) + octokit (4.14.0) sawyer (~> 0.8.0, >= 0.5.3) parslet (1.5.0) blankslate (~> 2.0) - posix-spawn (0.3.12) + posix-spawn (0.3.13) public_suffix (1.5.3) pygments.rb (0.6.3) posix-spawn (~> 0.3.6) yajl-ruby (~> 1.2.0) - rb-fsevent (0.9.8) - rb-inotify (0.9.7) - ffi (>= 0.5.0) - rdiscount (2.1.7) - redcarpet (3.3.2) - rouge (2.0.7) - safe_yaml (1.0.4) - sass (3.4.22) + rb-fsevent (0.10.3) + rb-inotify (0.10.0) + ffi (~> 1.0) + rdiscount (2.1.8) + redcarpet (3.3.3) + rouge (3.3.0) + ruby_dep (1.5.0) + safe_yaml (1.0.5) + sass (3.7.3) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) sawyer (0.8.1) addressable (>= 2.3.5, < 2.6) faraday (~> 0.8, < 1.0) - terminal-table (1.7.3) - unicode-display_width (~> 1.1.1) - thread_safe (0.3.5) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) toml (0.1.2) parslet (~> 1.5.0) typhoeus (0.8.0) ethon (>= 0.8.0) - tzinfo (1.2.2) + tzinfo (1.2.5) thread_safe (~> 0.1) - unicode-display_width (1.1.1) - yajl-ruby (1.2.1) + unicode-display_width (1.5.0) + yajl-ruby (1.2.3) PLATFORMS ruby @@ -144,4 +157,4 @@ DEPENDENCIES rouge BUNDLED WITH - 1.13.6 + 1.17.2 From 5bcc1427dbd4adb105addefc63c5a2c16e79ed61 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 1 Apr 2019 17:18:31 +0800 Subject: [PATCH 03/16] add copyright --- README.md | 7 +++-- _includes/welcome.md | 7 ----- _layouts/default.html | 37 +++++++++--------------- _layouts/page.html | 67 ++++++++++++++++++------------------------- 4 files changed, 46 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index afee6fa21..65ad05cc8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # PHP 之道 -[在线地址](https://laravel-china.github.io/php-the-right-way/) +[Github 在线地址](https://leo-yi.github.io/php-the-right-way/) +[国内在线地址](https://show.oyifan.com/php-the-right-way/) -> 此项目由 [Laravel China 社区](https://laravel-china.org/ ) 维护,请维护互联网开放精神,转载请保留出处。 +> 此项目由 [Leo Yi](https://blog.oyifan.com/ ) 个人维护,请维护互联网开放精神,转载请保留出处。 + +> 此项目 fork [Laravel China 社区](https://laravel-china.org/ ) 维护的仓库,因为此仓库2年不更新,提PR也没反应,才决定自己建立这个站,感谢 summer 做出的贡献。 ## 概览 diff --git a/_includes/welcome.md b/_includes/welcome.md index c75b55e3e..6f422cd22 100644 --- a/_includes/welcome.md +++ b/_includes/welcome.md @@ -42,12 +42,5 @@ _PHP: The Right Way_ 被翻译为以下版本: 帮助我们让本网站作为 PHP 新手的最佳资源![在 GitHub 上贡献][2] -## 推广 {#spread-the-word} - -_PHP: 您可以在网站上放置 PHP之道 的横幅来支持我们,让 PHP 的新人知道哪里可以获取到好的资料! - -[广告横幅][3] - [1]: https://leanpub.com/phptherightway -[3]: /banners.html [2]: https://github.com/codeguy/php-the-right-way/tree/gh-pages diff --git a/_layouts/default.html b/_layouts/default.html index e43b7efd5..3374eb669 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -24,13 +24,8 @@