Docker configuration nginx,php7,mysql

Download php7, mysql, nginx

$ docker pull php:7-fpm-alpine
$ docker pull nginx
$ docker pull mysql

Run php

在这里必须挂载目录到php-fpm, nginx不会直接执行,它检测到php文件,会把php文件的路径发到php-fpm去,php-fpm再依据nginx发过来的路径找到代码并执行啊。

$ docker run -it --rm --name xphp --link xmysql:xmysql -v /Users/zhouitpro/www/docker_web:/usr/share/nginx/html php:7-fpm-alpine
# --link xmysql:xmysql 映射mysql

Install php ext

# 安装pdo_mysql
$ docker exec -it run xphp bash
Docker# docker-php-ext-install pdo_mysql
Docker# docker-php-ext-enable pdo_mysql

Run Nginx

nginx config file

server {
    listen       80;
    server_name  localhost;
    root /usr/share/nginx/html/;
    location ~ \.php$ {
        fastcgi_pass xphp:9000; # 这里对应上面的php-fpm别名, php-fpm端口默认是9000
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
    location ~ /\.ht {
        deny  all;
    }
}
$ docker run -it --rm  --link xphp:xphp -v /Users/zhouitpro/www/docker_web:/usr/share/nginx/html  -v /Users/zhouitpro/www/docker/site.conf:/etc/nginx/conf.d/default.conf -p 9090:80  nginx

# -p 是转发端口 外部的 9090对应nginx提供的80端口
# --link 是映射上面的 php-fpm
# -v 是映射本地的web目录到nginx的www目录,和配置文件

Mysql

$ docker run -it --rm --name xmysql -e MYSQL_ROOT_PASSWORD=root mysql

HHVM

hhvm

$ brew install hhvm

安装Supervisord, 用于监控Supervisord并且可以自动重启hhvm当hhvm崩溃的时候

$ sudo easy_install supervisor
$ mkdir -p /usr/local/etc/supervisor.d/

Capistrano 自动部署

Install

$ gem install capistrano
$ cap install #初始化
$ cap production deploy #部署到在线
$ cap production deploy:rollback #回滚

config/deploy.rb
:application 应用名
:repo_url 远程仓库地址
:deploy_to 服务器目录

其它工具:
Deployer
Magallanes
Rocketeer

PHP 错误处理

/**
 * Error.
 *
 * 3rd comonpent:
 *   filp/whoops
 *   monolog/monolog error log
 */

set_error_handler(function($errno, $errstr, $errfile, $errline, $errorcontext) {

  if(!(error_reporting() & $errno)) {
    return;
  }

  throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});


var_dump($test);

PHP DatePeriod 周期

/**
 * DatePeriod
 *
 * 3rd component: https://github.com/briannesbitt/Carbon
 */


/**
 * DateInterval 表示到下一个周期的时间间隔.
 *
 * 2W表示两周.
 */
$interval = new DateInterval('P2W');
$start = new DateTime();

$periods = new DatePeriod($start, $interval, 3, DatePeriod::EXCLUDE_START_DATE);

foreach($periods as $nextDateTime) {
  var_dump($nextDateTime->format('Y-m-d'));
}

PHP Password Hashing

/**
* PHP Password
*
* author homepage: blog.ircmaxell.com
*
* Document: http://php.net/manual/zh/book.password.php
*/

/**
* generate
*/
$mypass = password_hash('mypassword', PASSWORD_DEFAULT, ['cost' => 12]);

/**
* validate.
*/
var_dump(password_verify('mypassword', $mypass));

Opcache配置

http://php.net/manual/zh/opcache.configuration.php

opcache.validate_timestamps = 1  #设置为1表示会间隔的检查PHP脚本的内容是否有变化, Production设置为0
opcache.revalidate_freq = 0 # 检查脚本时间戳是否有更新的周期,以秒为单位。 设置为 0 会导致针对每个请求, OPcache 都会检查脚本更新.
opcache.memory_consumption = 64 #OPcache 的共享内存大小, 为操作码缓存分配的内存 MB
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 4000  #操作码最多能缓存多少个PHP脚本
opcache.fast_shutdown = 1

面向对象进阶之:closure

/**
 * Class App
 *
 * 使用Closure bindTo实现路由添加.
 */
class App {
  protected $routers = [];
  protected $responseStatus = 200;
  protected $responseType = 'text/html';
  protected $responseBody = 'hello world';

  public function addRoute($routePath, Closure $routeCallback) {
    $this->routers[$routePath] = $routeCallback->bindTo($this, __CLASS__);
    return $this;
  }

  public function dispatch($currentPath = '') {
    if ($currentPath && isset($this->routers[$currentPath])) {
      $this->routers[$currentPath]();
    }

    header('HTTP/1.1 ' . $this->responseStatus);
    header('Content-type: ' . $this->responseType);
    header('Content-length: ' . mb_strlen($this->responseBody));
    print $this->responseBody;
  }

  public static function factory() {
    return new static();
  }
}

App::factory()->addRoute('home', function() {
  $this->responseBody = 'this is front page';
})->addRoute('news', function() {
  $this->responseBody = 'this is news page';
})->dispatch('news');