部署和测试工具 - PHP进阶 (5)

测试 概念分类 单元测试(Unit Test) - 在项目中独立测试函数、方法、类等。 TDD(Test-Driven Development) - 项目开始后,先写一部分测试用例,然后实现,然后继续写测试用例,继续实现,不断循环直至项目完成或终止。 BDD(Behavior-Driven Development) - 基于行为流程来描述程序的实现。类似于单元测试,只是在实现上应用了比较友好的表达方式便于理解。 SpecBDD - 面向开发人员。使用编程语言表达。例: phpspec StoryBDD - 面向产品经理。基于英语语言表达。例:behat 自动化部署工具 capistrano/capistrano magephp Rocketeer 代码分析工具 Xdebug blackfire

February 26, 2017 · 1 min · 28 words · Eric Yang

服务器配置及性能调优 - PHP进阶 (4)

PHP-FPM 配置 全局配置 emergency_restart_threshold = 10 如果子进程在 emergency_restart_interval 设定的时间内收到该参数设定次数的 SIGSEGV 或者 SIGBUS退出信息号,则FPM会重新启动。0 表示“关闭该功能”。默认值:0(关闭)。 emergency_restart_interval = 1m 用于设定平滑重启的间隔时间。这么做有助于解决加速器中共享内存的使用问题。 进程池配置 pm.max_requests = 1000 设置每个子进程重生之前服务的请求数。对于可能存在内存泄漏的第三方模块来说是非常有用的。如果设置为 ‘0’ 则一直接受请求,等同于 PHP_FCGI_MAX_REQUESTS 环境变量。默认值:0。 request_slowlog_timeout = 5s 当一个请求该设置的超时时间后,就会将对应的 PHP 调用堆栈信息完整写入到慢日志中。设置为 ‘0’ 表示 ‘Off’。 确定 PHP-FPM 的进程数 首先确定服务器可以分配给PHP的内存大小 其次确定单个PHP进程的内存消耗 最后确定进程数 上线前别忘了使用 Apache Bench 或者 Seige 来做压力测试 Zend OPcache 通俗来讲,OPcache 是用来预编译PHP的代码到缓存里来加速HTTP的请求。 Session 处理 由于PHP默认会将session以文件的形式存储在磁盘上,必然会加大磁盘的I/O,拖慢系统。使用内存存储的方式,比如 Memcached 或者 Redis 会是更好的选择。而且这种方式会便于以后扩展分布式系统时保证 Session 共享。

February 25, 2017 · 1 min · 60 words · Eric Yang

好的编程习惯 - PHP进阶 (3)

净化、验证、转义输入输出 需要注意的几个外部数据源 $_GET $_POST $_REQUEST $_COOKIE $argv php://stdin php://input file_get_contents() 远程数据库 远程 APIs 远程客户端获取的数据 净化输入 HTML 在接触存储层之前,使用 htmlentities() 来净化 HTML 的特殊字符: <?php $input = '<p><script>alert("You won the Nigerian lottery!");</script></p>'; echo htmlentities($input, ENT_QUOTES, 'UTF-8'); 避免使用 preg_replace(), preg_replace_all() 和 preg_replace_callback() 等正则函数在HTML代码里。 SQL 查询 使用 PDO prepared statement 的形式,避免SQL注入等问题。 用户信息收集 使用 filter_var() 和 filter_input() 来净化用户信息数据,如 emails, URL-encoded strings, integers, floats, HTML characters, URLs 等,例: <?php $email = 'john@example.com'; $emailSafe = filter_var($email, FILTER_SANITIZE_EMAIL); 验证数据 可以使用内置函数 filter_var() 来做简单的验证:...

February 20, 2017 · 4 min · 717 words · Eric Yang

PSR标准解读 - PHP进阶 (2)

PSR-0 自动加载的标准结构 (虽然已不被推荐使用,但composer还在支持) 要点 结构: \<Vendor Name>\(<Namespace>\)*<Class Name> 第一层级的命名为开发人员的标识 完整的命名空间可包含多个层级 在加载文件的时候,命名空间的分隔符\会被DIRECTORY_SEPARATOR替换 类名中的_会被DIRECTORY_SEPARATOR替换,所以_无任何意义 在加载文件的时候,命名空间会补全.php后缀 命名空间及类命名可以大小写随意 示例: \Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php \namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php 需要注意的是,层级目录会重复vendor和namespace。 加载器的实现示例 <?php function autoload($className) { $className = ltrim($className, '\\'); $fileName = ''; $namespace = ''; if ($lastNsPos = strrpos($className, '\\')) { $namespace = substr($className, 0, $lastNsPos); $className = substr($className, $lastNsPos + 1); $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; } $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; require $fileName; } spl_autoload_register('autoload'); ### PSR-1 基本代码样式 * 标签 (PHP tags) 代码必须包含在<?...

October 3, 2016 · 2 min · 268 words · Eric Yang

常规用法 - PHP进阶 (1)

命名空间 Namespace (PHP 5.3+) 沙盒机制。虚拟的层级关系,更好的隔离不同的组建。PS:以下仅为推荐用法。 声明、引用、别名 (Declear, Import, Alias) 声明: <?php // 必须在首行,推荐保持每个命名空间一行 namespace Symfony\Component\HttpFoundation; 引用 & 别名 // 推荐保持每个引用一行 Class <?php // 引用 use Symfony\Component\HttpFoundation\Response; $response = new Response('Oops', 400); $response->send(); // 别名 use Symfony\Component\HttpFoundation\Response as Res; $r = new Res('Oops', 400); $r->send(); ### Function (PHP 5.6+) <?php // 引用 use function My\Full\functionName; // 别名 use function My\Full\functionName as func; ### Constant // 引用 use const My\Full\CONSTANT; ### PHP 7+ code use some\namespace\{ClassA, ClassB, ClassC as C}; use function some\namespace\{fn_a, fn_b, fn_c}; use const some\namespace\{ConstA, ConstB, ConstC}; ### 全局命名空间 * 引用时不加入命名空间,程序默认为与当前命名空间相同 * 没有命名空间的程序,默认在global下,例如Exception。使用时需要在前边加上"...

August 1, 2016 · 3 min · 430 words · Eric Yang

优化配置 Nginx 和 PHP-FPM

nginx server_tokens off; hide nginx server tokens access_log off; reduce nginx write to disk times worker_processes 1; always equals grep processor /proc/cpuinfo | wc -l worker_connections 4096; ulimit -n will echo the max connection of server. client_body_buffer_size 32K; This handles the client buffer size, meaning any POST actions sent to Nginx. client_header_buffer_size 10k; large_client_header_buffers 4 32k; client_max_body_size 50m; Gzip Compression Gzip can help reduce the amount of network transfer Nginx deals with....

September 10, 2015 · 2 min · 367 words · Eric Yang

使用Supervisor来守护Laravel Queue进程

安装Supervisor sudo apt-get install supervisor 编辑Queue守护进程 sudo vi /etc/supervisor/conf.d/myqueue.conf [program:myqueue] command = php artisan queue:work --env=production --queue=queue1,queue2 user = www-data directory = /path/to/app/ process_name = %(program_name)s_%(process_num)s numprocs = 6 autostart = true autorestart = true stdout_logfile = /path/to/app/app/storage/logs/supervisor-pd-queue.log stdout_logfile_maxbytes = 10MB stderr_logfile = /path/to/app/app/storage/logs/supervisor-pd-queue.log stderr_logfile_maxbytes = 10MB 启动进程 $ sudo supervisorctl > reread # Tell supervisord to check for new items in /etc/supervisor/conf.d/ > add myqueue # Add this process to Supervisord > start myqueue # May say “already started” 查看进程是否启动 $ ps aux | grep php

January 14, 2015 · 1 min · 87 words · Eric Yang