ThinkPHP 3.2 使用的一些记录

在 View 模板引擎中输出数组的下标值

如 数组 $list 和 下标 $data.vo.id

{$list[$data[vo][id]]}

若变量为空,赋予默认值(判断空)

{$vo.position_id|default='空'}

获得 MySQL 数据表备注

//获取备注信息
public function _get_field() {
  $model = new \Think\Model();
  $controller_name = $this->CamelCaseToUnderScore(CONTROLLER_NAME);
  $rs = $model->query("select `column_name`,`column_comment` from information_schema.COLUMNS WHERE TABLE_SCHEMA = '".C('DB_NAME')."' AND TABLE_NAME = '".C('DB_PREFIX').$controller_name."'");

  $arr = array_column($rs,'column_comment','column_name');
  return $arr;
}
//驼峰命名转下划线命名
public function CamelCaseToUnderScore($str)
{
  $dstr = preg_replace_callback('/([A-Z]+)/',function($matchs)
  {
    return '_'.strtolower($matchs[0]);
  },$str);
  return trim(preg_replace('/_{2,}/','_',$dstr),'_');
}

PHP 数组变量传递给 JS

var arr=transArr({$array|json_encode=true}); 
function transArr(obj) {
  var tem=[];
  $.each(obj, function(i) {
	tem[i]=obj[i];
  });
  return tem;
}

ThinkPHP 使用 WorkerMan 的一些记录

通过 composer 安装

composer require topthink/think-worker

启动

php think worker

初次使用可能会报错

[root@instance-jewlel2q www.imgram.cn]# php think worker
Starting Workerman http server...
Workerman[think] start in DEBUG mode
stream_socket_server() has been disabled for security reasons in file /home/wwwroot/www.imgram.cn/vendor/workerman/workerman/Worker.php on line 2178

原因是 stream_socket_server 函数被 php.ini 禁用

  • 运行 php –ini 找到 php.ini 文件
  • 打开 php.ini 找到 disable_functions 一项,将 stream_socket_server 禁用项删掉。
  • 重启 php-fpm。

ThinkPHP 5 引入 百度云 BaiduBCE SDK

项目根目录使用 Composer

composer require baidubce/bce-sdk-php

在 Controller 中引入

<?php
require '../vendor/autoload.php';//这句不用,自动引入
use BaiduBce\Services\Bos\BosClient;

测试连接

public function baidu(){
  $BOS_TEST_CONFIG =
	array(
	  'credentials' => array(
	  'accessKeyId' => '684b94f7675142d79ed2bxxxxxxxxxxx',
	  'secretAccessKey' => '0ee6b11cc38445fc8xxxxxxxxxxxxx',
	  ),
	  'endpoint' => 'https://todo.cdn.bcebos.com',
	);
  $client = new BosClient($BOS_TEST_CONFIG);
  dump($client);
}

输出结果

上传文件测试

public function baidu(){
  $BOS_TEST_CONFIG =
    array(
      'credentials' => array(
      'accessKeyId' => '684b94f7675142d79ed2bxxxxxxxxxxx',
      'secretAccessKey' => '0ee6b11cc38445fc8xxxxxxxxxxxxx',
      'sessionToken' => ''
      ),
    'endpoint' => 'https://todo.cdn.bcebos.com',
    'stsEndpoint' => '',
  );
  $client = new BosClient($BOS_TEST_CONFIG);
  $bucketName = 'path';
  $a = $client->putObjectFromFile($bucketName, 'abc.png', 'tmp/x.png');
  dump($a);
}

如果用的是百度的服务器,可能出现在线报错

[curl] 6: Could not resolve host: todo.cdn.bcebos.com; Unknown error [url] 

DNS 的问题

vim /etc/resolv.conf 

修改

但是修改 DNS 的方式会使无法使用内网传输,

所以需要将上传地址改为官方域名,不要用 CDN 加速域名,这样百度内网服务器之间网就可以妙传了

Linux 下 ThinkPHP 与 Swoole 搭配 ThinkPHP 性能对比测试

ThinkPHP 5.0.21

Server Software:        nginx
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /
Document Length:        39 bytes

Concurrency Level:      10
Time taken for tests:   9.064 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      218000 bytes
HTML transferred:       39000 bytes
Requests per second:    110.33 [#/sec] (mean)
Time per request:       90.637 [ms] (mean)
Time per request:       9.064 [ms] (mean, across all concurrent requests)
Transfer rate:          23.49 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       1
Processing:    15   90  37.8     87     217
Waiting:       15   90  37.8     87     217
Total:         15   90  37.8     88     217

Swoole 搭配 ThinkPHP 5.0.21

Server Software:        swoole-http-server
Server Hostname:        127.0.0.1
Server Port:            9501

Document Path:          /
Document Length:        39 bytes

Concurrency Level:      10
Time taken for tests:   4.355 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1870000 bytes
HTML transferred:       390000 bytes
Requests per second:    2296.38 [#/sec] (mean)
Time per request:       4.355 [ms] (mean)
Time per request:       0.435 [ms] (mean, across all concurrent requests)
Transfer rate:          419.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       6
Processing:     1    4   3.7      4     166
Waiting:        0    4   3.6      3     166
Total:          1    4   3.7      4     166

配置信息

Swoole 适配 ThinkPHP 5 ab 压力测试 与 原生 ThinkPHP 对比

swoole 适配 thinkphp 5.0.21

Server Software:        swoole-http-server
Server Hostname:        127.0.0.1
Server Port:            9501

Document Path:          /
Document Length:        39 bytes

Concurrency Level:      10
Time taken for tests:   2.378 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1870000 bytes
HTML transferred:       390000 bytes
Requests per second:    4204.38 [#/sec] (mean)
Time per request:       2.378 [ms] (mean)
Time per request:       0.238 [ms] (mean, across all concurrent requests)
Transfer rate:          767.79 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       2
Processing:     1    2   1.2      2      21
Waiting:        1    2   1.1      2      21
Total:          1    2   1.1      2      21

与原生 ThinkPHP 对比

Server Software:        nginx/1.15.3
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /index.php
Document Length:        39 bytes

Concurrency Level:      10
Time taken for tests:   48.468 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      2020000 bytes
HTML transferred:       390000 bytes
Requests per second:    206.32 [#/sec] (mean)
Time per request:       48.468 [ms] (mean)
Time per request:       4.847 [ms] (mean, across all concurrent requests)
Transfer rate:          40.70 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2  75.8      0    3611
Processing:     9   45  73.4     42    3651
Waiting:        9   45  73.4     42    3651
Total:          9   47 105.2     42    3651

原生 PHP 输出 hello world

Server Software:        nginx/1.15.3
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /hello_world.php
Document Length:        11 bytes

Concurrency Level:      10
Time taken for tests:   0.870 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      870000 bytes
HTML transferred:       55000 bytes
Requests per second:    5749.02 [#/sec] (mean)
Time per request:       1.739 [ms] (mean)
Time per request:       0.174 [ms] (mean, across all concurrent requests)
Transfer rate:          976.88 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       2
Processing:     1    2   0.5      1       5
Waiting:        1    1   0.4      1       4
Total:          1    2   0.5      2       5

本机配置

Swoole 适配 ThinkPHP 5.0.21

新增代码

server/http_server.php

<?php
/**
 * Created by PhpStorm.
 * User: guofeng
 * Date: 2018/9/8
 * Time: 上午11:21
 */

$http = new swoole_http_server('0.0.0.0',9501);
$http->set([
    'enable_static_handler'=>true,
    'document_root'=>'../public/static',
    'worker_num'=>4,
]);
$http->on('WorkerStart',function(swoole_server $server,$worker_id){
    // 定义应用目录
    define('APP_PATH', __DIR__ . '/../application/');
    // ThinkPHP 引导文件
    // 1. 加载基础文件
    require __DIR__ . '/../thinkphp/base.php';
});
$http->on('request',function ($request,$response) use($http){

    $_SERVER = [];
    if(isset($request->server)){
        foreach($request->server as $k => $v){
            $_SERVER[strtoupper($k)] = $v;
        }
    }

    if(isset($request->header)){
        foreach($request->header as $k => $v){
            $_SERVER[strtoupper($k)] = $v;
        }
    }

    $_GET = [];
    if(isset($request->get)){
        foreach($request->get as $k => $v){
            $_GET[$k] = $v;
        }
    }

    $_POST = [];
    if(isset($request->post)){
        foreach($request->post as $k => $v){
            $_POST[$k] = $v;
        }
    }

    // 2. 执行应用
    ob_start();

    try{
        think\App::run()->send();
    }catch (\Exception $e){
        //todo
    }

    $res = ob_get_contents();
    ob_end_clean();
    $response->end($res);
});
$http->start();

ThinkPHP 核心文件修改

thinkphp/library/think/Request.php

/**
 * 获取当前请求URL的pathinfo信息(含URL后缀)
 * @access public
 * @return string
 */
public function pathinfo()
{
    if(isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] !='/'){
        return ltrim($_SERVER['PATH_INFO'], '/');
    }
    //if (is_null($this->pathinfo)) {
        if (isset($_GET[Config::get('var_pathinfo')])) {
            // 判断URL里面是否有兼容模式参数
            $_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')];
            unset($_GET[Config::get('var_pathinfo')]);
        } elseif (IS_CLI) {
            // CLI模式下 index.php module/controller/action/params/...
            $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
        }

        // 分析PATHINFO信息
        if (!isset($_SERVER['PATH_INFO'])) {
            foreach (Config::get('pathinfo_fetch') as $type) {
                if (!empty($_SERVER[$type])) {
                    $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?
                    substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];
                    break;
                }
            }
        }
        $this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/');
    //}
    return $this->pathinfo;
}
/**
 * 获取当前请求URL的pathinfo信息(不含URL后缀)
 * @access public
 * @return string
 */
public function path()
{
    //if (is_null($this->path)) {
        $suffix   = Config::get('url_html_suffix');
        $pathinfo = $this->pathinfo();
        if (false === $suffix) {
            // 禁止伪静态访问
            $this->path = $pathinfo;
        } elseif ($suffix) {
            // 去除正常的URL后缀
            $this->path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);
        } else {
            // 允许任何后缀访问
            $this->path = preg_replace('/\.' . $this->ext() . '$/i', '', $pathinfo);
        }
    //}
    return $this->path;
}

访问方式

命令行 启动

php http_server.php

访问地址

http://localhost:9501/?s=index/index/index
http://localhost:9501/index/index/index

ThinkPHP 3.2 连接多数据库

<?php

return array(
    /* 数据库设置 */
    'DB_TYPE'               =>  'mysqli',     // 数据库类型
    'DB_HOST'               =>  'localhost', // 服务器地址 rds190co1ii65n556p9v.mysql.rds.aliyuncs.com
    'DB_NAME'               =>  'kh',          // 数据库名
    'DB_USER'               =>  'root',      // 用户名
    'DB_PWD'                =>  'root',          // 密码
    'DB_PORT'               =>  '3306',        // 端口
    'DB_PREFIX'             =>  'bj_',    // 数据库表前缀
    'DB_PARAMS'          	=>  array(), // 数据库连接参数
    'DB_DEBUG'  			=>  TRUE, // 数据库调试模式 开启后可以记录SQL日志
    'DB_FIELDS_CACHE'       =>  true,        // 启用字段缓存
    'DB_CHARSET'            =>  'utf8',      // 数据库编码默认采用utf8
    'DB_DEPLOY_TYPE'        =>  0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
    'DB_RW_SEPARATE'        =>  false,       // 数据库读写是否分离 主从式有效
    'DB_MASTER_NUM'         =>  1, // 读写分离后 主服务器数量
    'DB_SLAVE_NO'           =>  '', // 指定从服务器序号
    'DB_CONFIG2'=>array(
        /* 数据库设置 */
        'DB_TYPE'               =>  'mysqli',     // 数据库类型
        'DB_HOST'               =>  'localhost', // 服务器地址 rds190co1ii65n556p9v.mysql.rds.aliyuncs.com
        'DB_NAME'               =>  'ald',          // 数据库名
        'DB_USER'               =>  'root',      // 用户名
        'DB_PWD'                =>  'root',          // 密码
        'DB_PORT'               =>  '3306',        // 端口
        'DB_PREFIX'             =>  'ocenter_',    // 数据库表前缀
        'DB_PARAMS'          	=>  array(), // 数据库连接参数
        'DB_DEBUG'  			=>  TRUE, // 数据库调试模式 开启后可以记录SQL日志
        'DB_FIELDS_CACHE'       =>  true,        // 启用字段缓存
        'DB_CHARSET'            =>  'utf8',      // 数据库编码默认采用utf8
        'DB_DEPLOY_TYPE'        =>  0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
        'DB_RW_SEPARATE'        =>  false,       // 数据库读写是否分离 主从式有效
        'DB_MASTER_NUM'         =>  1, // 读写分离后 主服务器数量
        'DB_SLAVE_NO'           =>  '', // 指定从服务器序号
    )
);
使用默认的:M('tablename')
使用第二个:M('tablename','表前缀','DB_CONFIG2')

 

MySQL 中支持 emoji 表情的存储 ThinkPHP

MySQL 的 utf8 编码的一个字符最多 3 个字节,但是一个 emoji 表情为 4 个字节,所以 utf8 不支持存储 emoji 表情。但是 utf8 的超集 utf8mb4 一个字符最多能有 4 字节,所以能支持 emoji 表情的存储。下面介绍了关于如何修改 mysql 数据库的编码格式变为 utf8mb4 的具体方法。

找到 /etc/ 路径下的 my.cnf 文件(或 /etc/mysql/ 路径下),通过 vim 命令 vim /etc/my.cnf 打开该文件并进行编辑,需添加如下所示配置:

[client]
default-character-set=utf8mb4

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect=’SET NAMES utf8mb4'

[mysql]
default-character-set=utf8mb4

Continue reading MySQL 中支持 emoji 表情的存储 ThinkPHP