PHP

PHP

Daily Tips: the function array_reduce, which can calculate the sum of the multidimensional array.

PHP网站管理员 Published the article • 0 comments • 54 views • 2019-07-26 00:35 • 来自相关话题

Sometimes, if you need to calculate the sum of an array, you may use the function `array_sum` in PHP.

> But this is the multidimensional array, like following:

### For example
```php 查看全部
Sometimes, if you need to calculate the sum of an array, you may use the function `array_sum` in PHP.

> But this is the multidimensional array, like following:

### For example
```php
$array = [
[
'quantity' => 2,
],
[
'quantity' => 4,
],
[
'quantity' => 5,
],
];

var_dump(array_sum($array)); // the result is 0, incorrect
```

This is incorrect, when you use the function `array_sum` to calculate the array, you will get the result `0`.

For this moment, the function `array_reduce` will help us to calculate the multidimensional array.

### The correct usage
```php
$sum = array_reduce($array, function($init, $datum) {
return $init + $datum['quantity'];
});
var_dump($sum); // int(11)
```

the function `array_reduce` has a callback function, which function has two parameters.

>The first parameter to the callback is an accumulator where the result-in-progress is effectively assembled. If you supply an $initial value the accumulator starts out with that value, otherwise, it starts out null.
The second parameter is where each value of the array is passed during each step of the reduction.
The return value of the callback becomes the new value of the accumulator. When the array is exhausted, array_reduce() returns accumulated value.

### Reference

1. [array_reduce](https://www.php.net/manual/zh/ ... ce.php)

Ubuntu下安装php7.2的gd库时,解决php7.2-gd : Depends: libjpeg62-turbo (>= 1.3.1) but it is not installable

PHP网站管理员 Published the article • 2 comments • 704 views • 2019-04-03 18:44 • 来自相关话题

### 背景

由于Ubuntu引导区坏了,无法找回boot中的文件,只能重新在虚拟机上重装系统,配置php的环境。

开始学php的时候我比较喜欢折腾源码,编译安装,期间走过很多的坑,这样会有一个问题,比如你需要添加一个扩展的时候你又需要编译一下扩展,有的时候编译源码的时候忘了编译某个模块就需要重新编译源码,比如thread模块,累了倦了,于是就开始用集成环境,或者用源安装。

### 问题

网上有很多的教程,千篇一律,无非都是这里这里复制那里粘贴的,遇到一些细节的问题,就懵逼了。

网上关于Ubuntu用软件源安装php7.2的教程是:
```bash

wget /etc/apt/trusted.gpg.d/php.gpg https://mirror.xtom.com.hk/sury/php/apt.gpg
sh -c 'echo "deb https://mirror.xtom.com.hk/sury/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
apt-get update

apt install php7.2-fpm php7.2-mysql php7.2-curl php7.2-gd php7.2-mbstring php7.2-xml php7.2-xmlrpc php7.2-zip php7.2-opcache -y
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php/7.2/fpm/php.ini
systemctl restart php7.2-fpm
```

### 解决方案

> 但是这里有些问题:

1. $(lsb_release -sc) 返回的是```zesty```,但是战源根本就没有这个目录,所以这里我们需要写死
. ```sh -c 'echo "deb https://mirror.xtom.com.hk/sury/php/ jessie main" > /etc/apt/sources.list.d/php.list'```

2. 安装php7.2-gd的时候出现如下问题:
```
The following packages have unmet dependencies:
php7.2-gd : Depends: libjpeg62-turbo (>= 1.3.1) but it is not installable
E: Unable to correct problems, you have held broken packages.
root@ubuntu:/mnt# apt-get install libjpeg62-tuls
Reading package lists... Done
Building dependency tree
Reading state information... Done
```

从```https://packages.debian.org/je ... nload```上下载libjpeg62-turbo的deb
```bash
cd /mnt
wget http://security.debian.org/deb ... 6.deb
dpkg -i libjpeg62-turbo_1.3.1-12+deb8u2_i386.deb

apt-get install php7.2-gd
```

### 思考

> 出现问题的时候我们很依赖搜索引擎来帮我们处理问题,有的时候我们很难集中注意力去审查问题,搜索引擎搜索一通之后,发现网上的教程或者解决方案千篇一律,甚至无法解决你的问题。浪费时间和精力。
> 这个时候我们需要静下心来想这个问题,是否以前遇到相同的问题,是否能够举一反三。 查看全部
### 背景

由于Ubuntu引导区坏了,无法找回boot中的文件,只能重新在虚拟机上重装系统,配置php的环境。

开始学php的时候我比较喜欢折腾源码,编译安装,期间走过很多的坑,这样会有一个问题,比如你需要添加一个扩展的时候你又需要编译一下扩展,有的时候编译源码的时候忘了编译某个模块就需要重新编译源码,比如thread模块,累了倦了,于是就开始用集成环境,或者用源安装。

### 问题

网上有很多的教程,千篇一律,无非都是这里这里复制那里粘贴的,遇到一些细节的问题,就懵逼了。

网上关于Ubuntu用软件源安装php7.2的教程是:
```bash

wget /etc/apt/trusted.gpg.d/php.gpg https://mirror.xtom.com.hk/sury/php/apt.gpg
sh -c 'echo "deb https://mirror.xtom.com.hk/sury/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
apt-get update

apt install php7.2-fpm php7.2-mysql php7.2-curl php7.2-gd php7.2-mbstring php7.2-xml php7.2-xmlrpc php7.2-zip php7.2-opcache -y
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php/7.2/fpm/php.ini
systemctl restart php7.2-fpm
```

### 解决方案

> 但是这里有些问题:

1. $(lsb_release -sc) 返回的是```zesty```,但是战源根本就没有这个目录,所以这里我们需要写死
. ```sh -c 'echo "deb https://mirror.xtom.com.hk/sury/php/ jessie main" > /etc/apt/sources.list.d/php.list'```

2. 安装php7.2-gd的时候出现如下问题:
```
The following packages have unmet dependencies:
php7.2-gd : Depends: libjpeg62-turbo (>= 1.3.1) but it is not installable
E: Unable to correct problems, you have held broken packages.
root@ubuntu:/mnt# apt-get install libjpeg62-tuls
Reading package lists... Done
Building dependency tree
Reading state information... Done
```

从```https://packages.debian.org/je ... nload```上下载libjpeg62-turbo的deb
```bash
cd /mnt
wget http://security.debian.org/deb ... 6.deb
dpkg -i libjpeg62-turbo_1.3.1-12+deb8u2_i386.deb

apt-get install php7.2-gd
```

### 思考

> 出现问题的时候我们很依赖搜索引擎来帮我们处理问题,有的时候我们很难集中注意力去审查问题,搜索引擎搜索一通之后,发现网上的教程或者解决方案千篇一律,甚至无法解决你的问题。浪费时间和精力。
> 这个时候我们需要静下心来想这个问题,是否以前遇到相同的问题,是否能够举一反三。


PHP Fatal error: Uncaught TypeError: Return value of PackageVersions

PHP网站管理员 Published the article • 0 comments • 691 views • 2019-02-26 15:20 • 来自相关话题

使用```composer update```更新扩展的时候出现如下错误,大概意识就是未捕获的类型错误,返回的类型必须是void。原来还好好的,怎么突然就不行了。

```
PHP Fatal error: Uncaught TypeError: Return value of PackageVersions\Installer::activate() must be an instance of PackageVersions\void, none returned in /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php:62
Stack trace:
#0 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(236): PackageVersions\Installer->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#1 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(PackageVersions\Installer))
#2 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(261): Composer\Plugin\PluginManager->registerPackage(Object(Composer\Package\CompletePackage))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(79): Composer\Plugin\PluginManager->loadRepository(Object(Composer\Repository\InstalledFilesystemRepository))
#4 phar:///usr/local/bin/composer/src/Composer/Factory.php(384): Composer\Plugin\PluginManager->loadInstalledPlugi in /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php on line 62
```

### 解决方案:

1. 执行如下命令,将最后的```:void```删除即可:
```bash
vim /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php +62
```

2. 其实出现这个问题是因为php版本过低导致的,php7.0之后支持限定返回类型,如果无返回则是```void```。出现如下问题你应该做的是更新你的php版本,或者```找到该主机上更高的php版本```,然后通过软链的方式,修改```/usr/bin/php```的快捷方式。

### 出现问题的原因
我主机的php版本一直是php7.+,但是由于执行了```apt-get update```和```apt-get upgrade```之后更新了php的依赖,导致php的软链也出现了变化,执行```php -v```得到的版本的是5.6。原来是装了两个php的版本。 查看全部

使用```composer update```更新扩展的时候出现如下错误,大概意识就是未捕获的类型错误,返回的类型必须是void。原来还好好的,怎么突然就不行了。

```
PHP Fatal error: Uncaught TypeError: Return value of PackageVersions\Installer::activate() must be an instance of PackageVersions\void, none returned in /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php:62
Stack trace:
#0 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(236): PackageVersions\Installer->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#1 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(PackageVersions\Installer))
#2 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(261): Composer\Plugin\PluginManager->registerPackage(Object(Composer\Package\CompletePackage))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(79): Composer\Plugin\PluginManager->loadRepository(Object(Composer\Repository\InstalledFilesystemRepository))
#4 phar:///usr/local/bin/composer/src/Composer/Factory.php(384): Composer\Plugin\PluginManager->loadInstalledPlugi in /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php on line 62
```

### 解决方案:

1. 执行如下命令,将最后的```:void```删除即可:
```bash
vim /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php +62
```

2. 其实出现这个问题是因为php版本过低导致的,php7.0之后支持限定返回类型,如果无返回则是```void```。出现如下问题你应该做的是更新你的php版本,或者```找到该主机上更高的php版本```,然后通过软链的方式,修改```/usr/bin/php```的快捷方式。

### 出现问题的原因
我主机的php版本一直是php7.+,但是由于执行了```apt-get update```和```apt-get upgrade```之后更新了php的依赖,导致php的软链也出现了变化,执行```php -v```得到的版本的是5.6。原来是装了两个php的版本。

如何优雅的解决composer添加扩展之后,提交git项目扩展变成了git子模块

PHP网站管理员 Published the article • 0 comments • 432 views • 2019-02-26 10:45 • 来自相关话题

### 出现composer git submodule背景

在php项目中,使用composer引入新的扩展的时候遇到了一个错误,三方扩展变成了这个项目的子项目,提交代码之后,这个扩展编程了```git submodule```,实际上我们提交之后的不是一个目录,```vendor```里面的这个项目是一个空的文件,导致线上引入资源而出现了故障。

在网上搜索了一下这个问题《composer安装后插件被当成GIT submodule(GIT子项目)》?网上给了三种解答,但是都不能解答我的问题,一方面他们说的不准确,还有可能说的不仔细吧。

### 出现这个问题的原因
composer在添加新的资源你的时候,如果项目是```git```仓库托管的,是通过```git clone```将代码拉至本地```vendor```目录的,所以该文件下会有一个```.git```的目录,这个其实是多余的,如果一个git托管的项目中再次出现git托管的项目,那么这个子项目就会被当做```submodule```被提交,

这里就不介绍```git submodule```了。

### 解决方案
如果解决这个问题呢?当然是直接删除扩展的```.git```目录了啦!需要每次手动将这个目录删除?每次更新之后还要删除?那么多的扩展都要一个一个的删除?

如果你很了解```composer```的处理机制的话,这些事情就变得十分的简单了。

```composer.json```中,我们可以在composer中自定义,composer处理过程中添加自己的钩子函数。脚本如下:找到vendor项目中所有的```.git```文件,然后执行```rm -rf```,即可。
```bash
find vendor -type d -name .git -exec rm -rf '{}' \;
```

composer.json的内容如下,在```post-install-cmd```和```post-update-cmd```执行之后执行我们的shell脚本:
```json
{
"scripts": {
"post-install-cmd": [
"find vendor -type d -name .git -exec rm -rf '{}' \\;",
],
"post-update-cmd": [
"find vendor -type d -name .git -exec rm -rf '{}' \\;",
]
},
}
``` 查看全部
### 出现composer git submodule背景

在php项目中,使用composer引入新的扩展的时候遇到了一个错误,三方扩展变成了这个项目的子项目,提交代码之后,这个扩展编程了```git submodule```,实际上我们提交之后的不是一个目录,```vendor```里面的这个项目是一个空的文件,导致线上引入资源而出现了故障。

在网上搜索了一下这个问题《composer安装后插件被当成GIT submodule(GIT子项目)》?网上给了三种解答,但是都不能解答我的问题,一方面他们说的不准确,还有可能说的不仔细吧。

### 出现这个问题的原因
composer在添加新的资源你的时候,如果项目是```git```仓库托管的,是通过```git clone```将代码拉至本地```vendor```目录的,所以该文件下会有一个```.git```的目录,这个其实是多余的,如果一个git托管的项目中再次出现git托管的项目,那么这个子项目就会被当做```submodule```被提交,

这里就不介绍```git submodule```了。

### 解决方案
如果解决这个问题呢?当然是直接删除扩展的```.git```目录了啦!需要每次手动将这个目录删除?每次更新之后还要删除?那么多的扩展都要一个一个的删除?

如果你很了解```composer```的处理机制的话,这些事情就变得十分的简单了。

```composer.json```中,我们可以在composer中自定义,composer处理过程中添加自己的钩子函数。脚本如下:找到vendor项目中所有的```.git```文件,然后执行```rm -rf```,即可。
```bash
find vendor -type d -name .git -exec rm -rf '{}' \;
```

composer.json的内容如下,在```post-install-cmd```和```post-update-cmd```执行之后执行我们的shell脚本:
```json
{
"scripts": {
"post-install-cmd": [
"find vendor -type d -name .git -exec rm -rf '{}' \\;",
],
"post-update-cmd": [
"find vendor -type d -name .git -exec rm -rf '{}' \\;",
]
},
}
```

唱吧歌词解密,php/python/java/golang解密唱吧歌词

PHP网站管理员 Published the article • 0 comments • 391 views • 2018-11-21 16:32 • 来自相关话题

如何用php语言解密唱吧歌词?
特定的算法需要要找秘钥,找到了秘钥问题就解决了一半,这个算法类似于凯撒加密,有一串秘钥,轮询秘钥按位取反即可

```php 查看全部

如何用php语言解密唱吧歌词?
特定的算法需要要找秘钥,找到了秘钥问题就解决了一半,这个算法类似于凯撒加密,有一串秘钥,轮询秘钥按位取反即可

```php

$content = file_get_contents('a89f8523a6724a915c6b2038c928b342.zrce');

$decryptCode = [-50, -45, 110, 105, 64, 90, 97, 119, 94, 50, 116, 71, 81, 54, -91, -68, ];
$data = '';
for ($i = 0; $i < strlen($content); $i++) {
$data .= chr(ord($content[$i]) ^ $decryptCode[$i % 16]);
}

print_r($data);
```

```
[refrain:44203-73402]
[ar:]
[ti:]
[total:175177]
[17090,4180]<0,228,0>在<228,228,0>没<456,456,0>风<912,228,0>的<1140,380,0>地<1520,532,0>方<2052,228,0>找<2280,456,0>太<2736,1444,0>阳
[24456,5243]<0,228,0>在<228,228,0>你<456,456,0>冷<912,228,0>的<1140,456,0>地<1596,456,0>方<2052,456,0>做<2508,456,0>暖<2964,2279,0>阳
[31832,1824]<0,228,0>人<228,228,0>事<456,228,0>纷<684,1140,0>纷
[34602,2622]<0,228,0>你<228,570,0>总<798,456,0>太<1254,342,0>天<1596,1026,0>真
[38924,1595]<0,228,0>往<228,228,0>后<456,228,0>的<684,228,0>余<925,670,0>生
```

解决php内存分配不足的问题:Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in

PHP网站管理员 Published the article • 0 comments • 442 views • 2018-10-17 12:33 • 来自相关话题

解决php内存分配不足的问题:Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in


### 背景

通常我们在执行php脚本的时候会遇到分配的内存被耗尽,出现内存分配不足的问题,程序无法继续运行下去
如果需要解决这个问题的话,我们需要修改```php.ini```中```memory_limit```的数值,默认是```128M```
```
Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M
```

PHP Fatal error: Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in /mnt/api-site/vendor/nikic/php-parser/lib/PhpParser/Lexer.php on line 280


### 解决方案

```bash
php --ini # 查看php.ini的位置

Configuration File (php.ini) Path: /usr/local/php/etc
Loaded Configuration File: /usr/local/php/etc/php.ini
Scan for additional .ini files in: /usr/local/php/conf.d
Additional .ini files parsed: /usr/local/php/conf.d/002-zendguardloader.ini

# 然后
vim /usr/local/php/etc/php.ini

# find the flag memory_limit
memory_limit = 526M # 修改为这个,如果不够,可以分配更多,1024M, 2048M等等
``` 查看全部

解决php内存分配不足的问题:Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in


### 背景

通常我们在执行php脚本的时候会遇到分配的内存被耗尽,出现内存分配不足的问题,程序无法继续运行下去
如果需要解决这个问题的话,我们需要修改```php.ini```中```memory_limit```的数值,默认是```128M```
```
Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M
```

PHP Fatal error: Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in /mnt/api-site/vendor/nikic/php-parser/lib/PhpParser/Lexer.php on line 280


### 解决方案

```bash
php --ini # 查看php.ini的位置

Configuration File (php.ini) Path: /usr/local/php/etc
Loaded Configuration File: /usr/local/php/etc/php.ini
Scan for additional .ini files in: /usr/local/php/conf.d
Additional .ini files parsed: /usr/local/php/conf.d/002-zendguardloader.ini

# 然后
vim /usr/local/php/etc/php.ini

# find the flag memory_limit
memory_limit = 526M # 修改为这个,如果不够,可以分配更多,1024M, 2048M等等
```

php处理excel读取导入导出excel文件

PHP网站管理员 Published the article • 0 comments • 420 views • 2018-10-11 18:21 • 来自相关话题

### php处理excel读取导入导出excel文件

### PHPOffice/PhpSpreadsheet
这是读取和编写excel电子表格的纯php库,支持如下格式:

|Format |Reading| Writing|
|:-|:-|:-|:-|
|Open Document Format/OASIS (.ods)| ✓ |✓|
|Office Open XML (.xlsx) Excel 2007 and above |✓ |✓|
|BIFF 8 (.xls) Excel 97 and above |✓ |✓|
|BIFF 5 (.xls) Excel 95 |✓ | |
|SpreadsheetML (.xml) Excel 2003 |✓ | |
|Gnumeric |✓ | |
|HTML |✓ |✓ |
|SYLK |✓ | |
|CSV |✓ |✓ |
|PDF (using either the TCPDF, Dompdf or mPDF libraries, which need to be installed separately) |✓ | |
### 通过```composer```导入到项目中
```bash
composer require phpoffice/phpspreadsheet
```

### 案例读取文件

```php 查看全部
### php处理excel读取导入导出excel文件

### PHPOffice/PhpSpreadsheet
这是读取和编写excel电子表格的纯php库,支持如下格式:

|Format |Reading| Writing|
|:-|:-|:-|:-|
|Open Document Format/OASIS (.ods)| ✓ |✓|
|Office Open XML (.xlsx) Excel 2007 and above |✓ |✓|
|BIFF 8 (.xls) Excel 97 and above |✓ |✓|
|BIFF 5 (.xls) Excel 95 |✓ | |
|SpreadsheetML (.xml) Excel 2003 |✓ | |
|Gnumeric |✓ | |
|HTML |✓ |✓ |
|SYLK |✓ | |
|CSV |✓ |✓ |
|PDF (using either the TCPDF, Dompdf or mPDF libraries, which need to be installed separately) |✓ | |
### 通过```composer```导入到项目中
```bash
composer require phpoffice/phpspreadsheet
```

### 案例读取文件

```php
require_once __DIR__ . '/vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\IOFactory;


$excelReader = IOFactory::createReader('Xlsx'); ·// 设置reader类型 xlsx
$sheet = $excelReader->load('demo.xlsx'); // 加载文件
$activeSheet = $sheet->getActiveSheet(); // 获取活跃的sheet
foreach ($activeSheet->getRowIterator() as $row) { // 迭代每一行
$cellIterator = $row->getCellIterator(); // 获取该行,列的迭代器
$cellIterator->setIterateOnlyExistingCells(FALSE);

foreach ($cellIterator as $cell) { // 迭代该行每一列
echo $cell->getValue(), PHP_EOL; // 获取行列所在位置的值
}
}
```

### 写文件,向excel文件中第一行第一列写入Hello World !
```php

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');

$writer = new Xlsx($spreadsheet);
$writer->save('hello-world.xlsx');
```

### 参考

- [github开源项目地址](https://github.com/PHPOffice/PhpSpreadsheet)
- [官方文档](https://phpspreadsheet.readthedocs.io/en/develop/)


php composer update mmap() cannot allocate memory

PHP网站管理员 Published the article • 0 comments • 1283 views • 2018-07-01 21:36 • 来自相关话题

## 背景

php项目执行composer update,出现如下错误:

## 错误输出

```bash
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Loading composer repositories with package information
Updating dependencies (including require-dev)

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory
PHP Fatal error: Out of memory (allocated 816848896) (tried to allocate 33554440 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 65

Fatal error: Out of memory (allocated 816848896) (tried to allocate 33554440 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 65
```

## 解决方案

```bash
apt-get update
apt-get upgrade

reboot
```

重启服务器 查看全部
## 背景

php项目执行composer update,出现如下错误:

## 错误输出

```bash
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Loading composer repositories with package information
Updating dependencies (including require-dev)

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory
PHP Fatal error: Out of memory (allocated 816848896) (tried to allocate 33554440 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 65

Fatal error: Out of memory (allocated 816848896) (tried to allocate 33554440 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 65
```

## 解决方案

```bash
apt-get update
apt-get upgrade

reboot
```

重启服务器

聊聊php的进程

PHP网站管理员 Published the article • 0 comments • 287 views • 2018-06-29 11:27 • 来自相关话题

# 聊聊php的进程

php是当进程执行的,php处理多并发的问题是主要是依赖服务器或者是PHP-FPM的多进程或者进程的复用,PHP实现多进程意义重大,处理大量数据或者后台守护程序是尤为重要。

## ```pcntl_fork``` 实现php多进程

需要加载```pcntl```扩展,而且这个扩展只能在linux环境先编译。

```pcntl_fork()```可以在当前进程,当前位置产生一个子进程,这个函数创建一个子进程后,子进程会继承父进程的上下文,和父进程一样,从```pcntl_fork()```的位置继续往下执行,
只是```pcntl_fork()```的返回值不同,由此,我们可以区分这个是父进程还是子进程,处理不同的逻辑。

- 由于系统初始进程init进程的```pid = 1```,所以父进程的返回值是大于1的
- 子进程返回值固定为0
- 如果```pcntl_fork()```返回值为-1时,说明fork失败了,当然也不会有子进程的存在。


## 代码实例

```php 查看全部

# 聊聊php的进程

php是当进程执行的,php处理多并发的问题是主要是依赖服务器或者是PHP-FPM的多进程或者进程的复用,PHP实现多进程意义重大,处理大量数据或者后台守护程序是尤为重要。

## ```pcntl_fork``` 实现php多进程

需要加载```pcntl```扩展,而且这个扩展只能在linux环境先编译。

```pcntl_fork()```可以在当前进程,当前位置产生一个子进程,这个函数创建一个子进程后,子进程会继承父进程的上下文,和父进程一样,从```pcntl_fork()```的位置继续往下执行,
只是```pcntl_fork()```的返回值不同,由此,我们可以区分这个是父进程还是子进程,处理不同的逻辑。

- 由于系统初始进程init进程的```pid = 1```,所以父进程的返回值是大于1的
- 子进程返回值固定为0
- 如果```pcntl_fork()```返回值为-1时,说明fork失败了,当然也不会有子进程的存在。


## 代码实例

```php

$ppid = posix_getpid();
$pid = pcntl_fork();

if ($pid == -1) {
echo 'fork fail', PHP_EOL;
} else if ($pid > 0) {
cli_set_process_title('php current pid:' . $pid);
echo 'fork success', PHP_EOL;
sleep(30);
} else {
$cpid = posix_getpid();
cli_set_process_title("php ppid: {$ppid}, children pid: {$cpid}.");
sleep(30);
}
```

## 函数介绍

- ```pcntl_fork()``` 创建一个子进程
- ```posix_getpid()``` 获取当前进程的pid
- ```cli_set_process_title($string)``` 为当前进程设置一个名称
- ```pcntl_signal(int $signo , callback $handler)```安装一个信号处理器, $signo是待处理的信号常量,callback是其处理函数
- ```pcntl_signal_dispatch()``` 调用每个等待信号通过pcntl_signal()安装的处理器
- ```posix_kill(int $pid , int $sig)``` 通过向子进程发送一个信号来操作子进程,如发送一个终止信号来结束子进程。
- ```pcntl_waitpid (int $pid , int &$status [, int $options = 0 ])``` 等待或者返回fork的子进程状态,如果子进程在此函数调用时已经退出(俗称僵尸进程),此函数
将立刻返回并且释放所有系统资源,此方法可避免子进程变成僵尸进程,造成系统资源你的浪费。

## 如何管理子进程 (信号)

> 在计算机科学中,信号是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。

这种异步通知机制就是```信号```。

### 分发信号处理器

我们通过父进程接收子进程传来的信号,判断子进程的状态,从而对子进程进行管理。
在父进程中使用```pcntl_signal()```和```pcntl_signal_dispatch```来给各自子进程安装信号处理器。

### 常见的信号

- SIGCHLD 子进程退出成为僵尸进程会向父进程发送这个信号
- SIGHUP 进程挂起
- SIGTEM 进程终止

执行下面的命令,我们可以看到全部的信号
```bash
root@ubuntu:~# kill -l
```

```text
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
```

安装好了信号处理器之后,一旦子进程有相应的信号返回给父进程,父进程就可以调用相应的callback函数对子进程进行处理。


PHP Composer 以及PSR规范

PHP网站管理员 Published the article • 0 comments • 1100 views • 2018-06-27 10:10 • 来自相关话题

## 背景说明

随着项目代码量的不断增加,以及一些库的依赖,我们不得不引入包的管理,来解决不易管理、阅读、模块化等问题。
三方库优秀,而且很多人在维护,功能对接也方便,我们没有必要在这个一个常用的功能上花费时间来封装或者造轮子,
很多人在自己的项目中都实践过,出现了问题,反应的issue也很快会被解决掉,功能也不断在完善。
一直强调,站在巨人的肩膀上,我们会走的更远,也许我们自己撸出来的代码难等大雅之堂,无法比拟,
把重心放在自己的核心产品和功能时间上,学会借鉴学习和使用,降低自己的开发成本。
也许有人会觉得我使用三方库可能会造成性能上的影响,有些功能我根本用不到。项目中代码有很多无用的代码,导致文件加载过慢,
其实不用担心, ```opcache```可以将php脚本预编译到共享内存中来提升php的性能。

## php Composer psr-4 autoload

Composer 是php用来管理依赖关系的工具,可以在项目中声明外部依赖的工具库,Composer会帮你安装这些依赖的库文件
psr-4 是一种代码规范,能够实现package的自动加载,规范了如何从文件路径自动加载类,同时也规范了自动加载文件的位置

## 自动加载

我们在支持Composer的项目中,只需引入这个文件,加上下面这段php的代码,就可以得到自动加载的支持了
```php 查看全部
## 背景说明

随着项目代码量的不断增加,以及一些库的依赖,我们不得不引入包的管理,来解决不易管理、阅读、模块化等问题。
三方库优秀,而且很多人在维护,功能对接也方便,我们没有必要在这个一个常用的功能上花费时间来封装或者造轮子,
很多人在自己的项目中都实践过,出现了问题,反应的issue也很快会被解决掉,功能也不断在完善。
一直强调,站在巨人的肩膀上,我们会走的更远,也许我们自己撸出来的代码难等大雅之堂,无法比拟,
把重心放在自己的核心产品和功能时间上,学会借鉴学习和使用,降低自己的开发成本。
也许有人会觉得我使用三方库可能会造成性能上的影响,有些功能我根本用不到。项目中代码有很多无用的代码,导致文件加载过慢,
其实不用担心, ```opcache```可以将php脚本预编译到共享内存中来提升php的性能。

## php Composer psr-4 autoload

Composer 是php用来管理依赖关系的工具,可以在项目中声明外部依赖的工具库,Composer会帮你安装这些依赖的库文件
psr-4 是一种代码规范,能够实现package的自动加载,规范了如何从文件路径自动加载类,同时也规范了自动加载文件的位置

## 自动加载

我们在支持Composer的项目中,只需引入这个文件,加上下面这段php的代码,就可以得到自动加载的支持了
```php

require_once __DIR __ . '/vendor/autoload.php';

```

## composer.json

```json
{
"autoload": {
"psr-4": {
"Work\\": "src/"
},
"psr-0": {
"Vendor_Namespace_": "src/"
}
}
}
```
Composer 将注册一个 PSR-4 autoloader 到 Work 命名空间, PSR-0 则支持```_```,自动转化为目录结构

### classmap

不遵循PSR-0/4规范的类库,

### files

明确的指定文件加载


## 额外的

### repositories 自定义资源包库

#### type
- composer Composer 类型的资源库,是一个简单的网络服务器上的
- vcs git、svn、hg等
- pear 从pear上获取资源
- package 内联一个```composer.json```对象


## scripts

Composer 允许你在安装过程中的各个阶段挂接脚本。

### [详细流程](http://docs.phpcomposer.com/articles/scripts.html)

### 典型的命令,composer安装时

- post-install-cmd ```composer install```执行之后触发
- post-update-cmd ```composer update```执行之后触发

### 自定义脚本demo

```json
{
"scripts": {
"post-update-cmd": "MyVendor\\MyClass::postUpdate",
"post-package-install": [
"MyVendor\\MyClass::postPackageInstall"
],
"post-install-cmd": [
"MyVendor\\MyClass::warmCache",
"phpunit -c app/",
"find vendor -type d -name .git -exec rm -rf '{}' \\;"
]
}
}
```

```php

namespace MyVendor;

use Composer\Script\Event;

class MyClass
{
public static function postUpdate(Event $event)
{
$composer = $event->getComposer();
// do stuff
}

public static function postPackageInstall(Event $event)
{
$installedPackage = $event->getOperation()->getPackage();
// do stuff
}

public static function warmCache(Event $event)
{
// make cache toasty
}
}
```

不然看出执行的脚本可以是一个类中的静态方法,当然也可以是一个函数,还可以是一条```shell```命令

我们也可以手动执行一些命令

```bash
composer run-script [--dev] [--no-dev] script
```

## 扩展

顺便了解一下其他的几个代码规范

### PSR

#### psr-0 自动加载

#### psr-1 [基本代码规范](https://www.php-fig.org/psr/psr-1/)

- 文件内只出现 ``` - 只是用```utf-8``` 没有BOM头的php代码 (必须)
- 声明新的类型符,不产生副作用
- 命名空间遵循```autoload```自动加载```psr-0/4```规范(必须)
- 类名驼峰(必须)
- 类中的常量下划线```_```分隔(必须)
- 方法驼峰(必须)


#### psr-2 [代码样式](https://www.php-fig.org/psr/psr-2/)

- 必须遵循psr-1
- 四个空格,而非tab
- 限制每行长度 80或者更少
- namespace 和 use 必须空格
- 类的括号必须独立一行
- 类的方法也一样
- 所有的属性和方法必须在修饰符之前,static在之后
- 关键词之后必须有空格
- 代码流程控制,```{``` 在一行,```}```独立一行
- ```{```之后没有空格,```}```之前没有空格

#### psr-3 [日志接口](https://www.php-fig.org/psr/psr-3/)

- 错误级别```RFC 5424``` (debug, info, notice, warning, error, critical, alert,
emergency)


#### psr-4 [自动加载](https://www.php-fig.org/psr/psr-4/)

相比于 psr-0 规范比较干净 PSR-0规范中下划线```_```会被转化成为目录分割线
上面有详细的介绍,这里就不再重复

#### psr-6 [缓存接口](https://www.php-fig.org/psr/psr-6/)


#### psr-7 [http消息接口](https://www.php-fig.org/psr/psr-7/)

#### psr-11 [容器接口](https://www.php-fig.org/psr/psr-11/)

#### psr-13 [超媒体链接](https://www.php-fig.org/psr/psr-13/)

#### psr-15 [http句柄](https://www.php-fig.org/psr/psr-15/)

#### psr-16 [简单缓存](https://www.php-fig.org/psr/psr-16/)


## 收集或者查看过的


- [php规范](https://www.php-fig.org)

- [python入门思维导图](http://naotu.baidu.com/file/a5 ... b2135e)

Daily Tips: the function array_reduce, which can calculate the sum of the multidimensional array.

PHP网站管理员 Published the article • 0 comments • 54 views • 2019-07-26 00:35 • 来自相关话题

Sometimes, if you need to calculate the sum of an array, you may use the function `array_sum` in PHP.

> But this is the multidimensional array, like following:

### For example
```php 查看全部
Sometimes, if you need to calculate the sum of an array, you may use the function `array_sum` in PHP.

> But this is the multidimensional array, like following:

### For example
```php
$array = [
[
'quantity' => 2,
],
[
'quantity' => 4,
],
[
'quantity' => 5,
],
];

var_dump(array_sum($array)); // the result is 0, incorrect
```

This is incorrect, when you use the function `array_sum` to calculate the array, you will get the result `0`.

For this moment, the function `array_reduce` will help us to calculate the multidimensional array.

### The correct usage
```php
$sum = array_reduce($array, function($init, $datum) {
return $init + $datum['quantity'];
});
var_dump($sum); // int(11)
```

the function `array_reduce` has a callback function, which function has two parameters.

>The first parameter to the callback is an accumulator where the result-in-progress is effectively assembled. If you supply an $initial value the accumulator starts out with that value, otherwise, it starts out null.
The second parameter is where each value of the array is passed during each step of the reduction.
The return value of the callback becomes the new value of the accumulator. When the array is exhausted, array_reduce() returns accumulated value.

### Reference

1. [array_reduce](https://www.php.net/manual/zh/ ... ce.php)

Ubuntu下安装php7.2的gd库时,解决php7.2-gd : Depends: libjpeg62-turbo (>= 1.3.1) but it is not installable

PHP网站管理员 Published the article • 2 comments • 704 views • 2019-04-03 18:44 • 来自相关话题

### 背景

由于Ubuntu引导区坏了,无法找回boot中的文件,只能重新在虚拟机上重装系统,配置php的环境。

开始学php的时候我比较喜欢折腾源码,编译安装,期间走过很多的坑,这样会有一个问题,比如你需要添加一个扩展的时候你又需要编译一下扩展,有的时候编译源码的时候忘了编译某个模块就需要重新编译源码,比如thread模块,累了倦了,于是就开始用集成环境,或者用源安装。

### 问题

网上有很多的教程,千篇一律,无非都是这里这里复制那里粘贴的,遇到一些细节的问题,就懵逼了。

网上关于Ubuntu用软件源安装php7.2的教程是:
```bash

wget /etc/apt/trusted.gpg.d/php.gpg https://mirror.xtom.com.hk/sury/php/apt.gpg
sh -c 'echo "deb https://mirror.xtom.com.hk/sury/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
apt-get update

apt install php7.2-fpm php7.2-mysql php7.2-curl php7.2-gd php7.2-mbstring php7.2-xml php7.2-xmlrpc php7.2-zip php7.2-opcache -y
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php/7.2/fpm/php.ini
systemctl restart php7.2-fpm
```

### 解决方案

> 但是这里有些问题:

1. $(lsb_release -sc) 返回的是```zesty```,但是战源根本就没有这个目录,所以这里我们需要写死
. ```sh -c 'echo "deb https://mirror.xtom.com.hk/sury/php/ jessie main" > /etc/apt/sources.list.d/php.list'```

2. 安装php7.2-gd的时候出现如下问题:
```
The following packages have unmet dependencies:
php7.2-gd : Depends: libjpeg62-turbo (>= 1.3.1) but it is not installable
E: Unable to correct problems, you have held broken packages.
root@ubuntu:/mnt# apt-get install libjpeg62-tuls
Reading package lists... Done
Building dependency tree
Reading state information... Done
```

从```https://packages.debian.org/je ... nload```上下载libjpeg62-turbo的deb
```bash
cd /mnt
wget http://security.debian.org/deb ... 6.deb
dpkg -i libjpeg62-turbo_1.3.1-12+deb8u2_i386.deb

apt-get install php7.2-gd
```

### 思考

> 出现问题的时候我们很依赖搜索引擎来帮我们处理问题,有的时候我们很难集中注意力去审查问题,搜索引擎搜索一通之后,发现网上的教程或者解决方案千篇一律,甚至无法解决你的问题。浪费时间和精力。
> 这个时候我们需要静下心来想这个问题,是否以前遇到相同的问题,是否能够举一反三。 查看全部
### 背景

由于Ubuntu引导区坏了,无法找回boot中的文件,只能重新在虚拟机上重装系统,配置php的环境。

开始学php的时候我比较喜欢折腾源码,编译安装,期间走过很多的坑,这样会有一个问题,比如你需要添加一个扩展的时候你又需要编译一下扩展,有的时候编译源码的时候忘了编译某个模块就需要重新编译源码,比如thread模块,累了倦了,于是就开始用集成环境,或者用源安装。

### 问题

网上有很多的教程,千篇一律,无非都是这里这里复制那里粘贴的,遇到一些细节的问题,就懵逼了。

网上关于Ubuntu用软件源安装php7.2的教程是:
```bash

wget /etc/apt/trusted.gpg.d/php.gpg https://mirror.xtom.com.hk/sury/php/apt.gpg
sh -c 'echo "deb https://mirror.xtom.com.hk/sury/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
apt-get update

apt install php7.2-fpm php7.2-mysql php7.2-curl php7.2-gd php7.2-mbstring php7.2-xml php7.2-xmlrpc php7.2-zip php7.2-opcache -y
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php/7.2/fpm/php.ini
systemctl restart php7.2-fpm
```

### 解决方案

> 但是这里有些问题:

1. $(lsb_release -sc) 返回的是```zesty```,但是战源根本就没有这个目录,所以这里我们需要写死
. ```sh -c 'echo "deb https://mirror.xtom.com.hk/sury/php/ jessie main" > /etc/apt/sources.list.d/php.list'```

2. 安装php7.2-gd的时候出现如下问题:
```
The following packages have unmet dependencies:
php7.2-gd : Depends: libjpeg62-turbo (>= 1.3.1) but it is not installable
E: Unable to correct problems, you have held broken packages.
root@ubuntu:/mnt# apt-get install libjpeg62-tuls
Reading package lists... Done
Building dependency tree
Reading state information... Done
```

从```https://packages.debian.org/je ... nload```上下载libjpeg62-turbo的deb
```bash
cd /mnt
wget http://security.debian.org/deb ... 6.deb
dpkg -i libjpeg62-turbo_1.3.1-12+deb8u2_i386.deb

apt-get install php7.2-gd
```

### 思考

> 出现问题的时候我们很依赖搜索引擎来帮我们处理问题,有的时候我们很难集中注意力去审查问题,搜索引擎搜索一通之后,发现网上的教程或者解决方案千篇一律,甚至无法解决你的问题。浪费时间和精力。
> 这个时候我们需要静下心来想这个问题,是否以前遇到相同的问题,是否能够举一反三。


PHP Fatal error: Uncaught TypeError: Return value of PackageVersions

PHP网站管理员 Published the article • 0 comments • 691 views • 2019-02-26 15:20 • 来自相关话题

使用```composer update```更新扩展的时候出现如下错误,大概意识就是未捕获的类型错误,返回的类型必须是void。原来还好好的,怎么突然就不行了。

```
PHP Fatal error: Uncaught TypeError: Return value of PackageVersions\Installer::activate() must be an instance of PackageVersions\void, none returned in /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php:62
Stack trace:
#0 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(236): PackageVersions\Installer->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#1 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(PackageVersions\Installer))
#2 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(261): Composer\Plugin\PluginManager->registerPackage(Object(Composer\Package\CompletePackage))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(79): Composer\Plugin\PluginManager->loadRepository(Object(Composer\Repository\InstalledFilesystemRepository))
#4 phar:///usr/local/bin/composer/src/Composer/Factory.php(384): Composer\Plugin\PluginManager->loadInstalledPlugi in /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php on line 62
```

### 解决方案:

1. 执行如下命令,将最后的```:void```删除即可:
```bash
vim /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php +62
```

2. 其实出现这个问题是因为php版本过低导致的,php7.0之后支持限定返回类型,如果无返回则是```void```。出现如下问题你应该做的是更新你的php版本,或者```找到该主机上更高的php版本```,然后通过软链的方式,修改```/usr/bin/php```的快捷方式。

### 出现问题的原因
我主机的php版本一直是php7.+,但是由于执行了```apt-get update```和```apt-get upgrade```之后更新了php的依赖,导致php的软链也出现了变化,执行```php -v```得到的版本的是5.6。原来是装了两个php的版本。 查看全部

使用```composer update```更新扩展的时候出现如下错误,大概意识就是未捕获的类型错误,返回的类型必须是void。原来还好好的,怎么突然就不行了。

```
PHP Fatal error: Uncaught TypeError: Return value of PackageVersions\Installer::activate() must be an instance of PackageVersions\void, none returned in /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php:62
Stack trace:
#0 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(236): PackageVersions\Installer->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#1 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(PackageVersions\Installer))
#2 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(261): Composer\Plugin\PluginManager->registerPackage(Object(Composer\Package\CompletePackage))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(79): Composer\Plugin\PluginManager->loadRepository(Object(Composer\Repository\InstalledFilesystemRepository))
#4 phar:///usr/local/bin/composer/src/Composer/Factory.php(384): Composer\Plugin\PluginManager->loadInstalledPlugi in /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php on line 62
```

### 解决方案:

1. 执行如下命令,将最后的```:void```删除即可:
```bash
vim /root/.composer/vendor/ocramius/package-versions/src/PackageVersions/Installer.php +62
```

2. 其实出现这个问题是因为php版本过低导致的,php7.0之后支持限定返回类型,如果无返回则是```void```。出现如下问题你应该做的是更新你的php版本,或者```找到该主机上更高的php版本```,然后通过软链的方式,修改```/usr/bin/php```的快捷方式。

### 出现问题的原因
我主机的php版本一直是php7.+,但是由于执行了```apt-get update```和```apt-get upgrade```之后更新了php的依赖,导致php的软链也出现了变化,执行```php -v```得到的版本的是5.6。原来是装了两个php的版本。

如何优雅的解决composer添加扩展之后,提交git项目扩展变成了git子模块

PHP网站管理员 Published the article • 0 comments • 432 views • 2019-02-26 10:45 • 来自相关话题

### 出现composer git submodule背景

在php项目中,使用composer引入新的扩展的时候遇到了一个错误,三方扩展变成了这个项目的子项目,提交代码之后,这个扩展编程了```git submodule```,实际上我们提交之后的不是一个目录,```vendor```里面的这个项目是一个空的文件,导致线上引入资源而出现了故障。

在网上搜索了一下这个问题《composer安装后插件被当成GIT submodule(GIT子项目)》?网上给了三种解答,但是都不能解答我的问题,一方面他们说的不准确,还有可能说的不仔细吧。

### 出现这个问题的原因
composer在添加新的资源你的时候,如果项目是```git```仓库托管的,是通过```git clone```将代码拉至本地```vendor```目录的,所以该文件下会有一个```.git```的目录,这个其实是多余的,如果一个git托管的项目中再次出现git托管的项目,那么这个子项目就会被当做```submodule```被提交,

这里就不介绍```git submodule```了。

### 解决方案
如果解决这个问题呢?当然是直接删除扩展的```.git```目录了啦!需要每次手动将这个目录删除?每次更新之后还要删除?那么多的扩展都要一个一个的删除?

如果你很了解```composer```的处理机制的话,这些事情就变得十分的简单了。

```composer.json```中,我们可以在composer中自定义,composer处理过程中添加自己的钩子函数。脚本如下:找到vendor项目中所有的```.git```文件,然后执行```rm -rf```,即可。
```bash
find vendor -type d -name .git -exec rm -rf '{}' \;
```

composer.json的内容如下,在```post-install-cmd```和```post-update-cmd```执行之后执行我们的shell脚本:
```json
{
"scripts": {
"post-install-cmd": [
"find vendor -type d -name .git -exec rm -rf '{}' \\;",
],
"post-update-cmd": [
"find vendor -type d -name .git -exec rm -rf '{}' \\;",
]
},
}
``` 查看全部
### 出现composer git submodule背景

在php项目中,使用composer引入新的扩展的时候遇到了一个错误,三方扩展变成了这个项目的子项目,提交代码之后,这个扩展编程了```git submodule```,实际上我们提交之后的不是一个目录,```vendor```里面的这个项目是一个空的文件,导致线上引入资源而出现了故障。

在网上搜索了一下这个问题《composer安装后插件被当成GIT submodule(GIT子项目)》?网上给了三种解答,但是都不能解答我的问题,一方面他们说的不准确,还有可能说的不仔细吧。

### 出现这个问题的原因
composer在添加新的资源你的时候,如果项目是```git```仓库托管的,是通过```git clone```将代码拉至本地```vendor```目录的,所以该文件下会有一个```.git```的目录,这个其实是多余的,如果一个git托管的项目中再次出现git托管的项目,那么这个子项目就会被当做```submodule```被提交,

这里就不介绍```git submodule```了。

### 解决方案
如果解决这个问题呢?当然是直接删除扩展的```.git```目录了啦!需要每次手动将这个目录删除?每次更新之后还要删除?那么多的扩展都要一个一个的删除?

如果你很了解```composer```的处理机制的话,这些事情就变得十分的简单了。

```composer.json```中,我们可以在composer中自定义,composer处理过程中添加自己的钩子函数。脚本如下:找到vendor项目中所有的```.git```文件,然后执行```rm -rf```,即可。
```bash
find vendor -type d -name .git -exec rm -rf '{}' \;
```

composer.json的内容如下,在```post-install-cmd```和```post-update-cmd```执行之后执行我们的shell脚本:
```json
{
"scripts": {
"post-install-cmd": [
"find vendor -type d -name .git -exec rm -rf '{}' \\;",
],
"post-update-cmd": [
"find vendor -type d -name .git -exec rm -rf '{}' \\;",
]
},
}
```

唱吧歌词解密,php/python/java/golang解密唱吧歌词

PHP网站管理员 Published the article • 0 comments • 391 views • 2018-11-21 16:32 • 来自相关话题

如何用php语言解密唱吧歌词?
特定的算法需要要找秘钥,找到了秘钥问题就解决了一半,这个算法类似于凯撒加密,有一串秘钥,轮询秘钥按位取反即可

```php 查看全部

如何用php语言解密唱吧歌词?
特定的算法需要要找秘钥,找到了秘钥问题就解决了一半,这个算法类似于凯撒加密,有一串秘钥,轮询秘钥按位取反即可

```php

$content = file_get_contents('a89f8523a6724a915c6b2038c928b342.zrce');

$decryptCode = [-50, -45, 110, 105, 64, 90, 97, 119, 94, 50, 116, 71, 81, 54, -91, -68, ];
$data = '';
for ($i = 0; $i < strlen($content); $i++) {
$data .= chr(ord($content[$i]) ^ $decryptCode[$i % 16]);
}

print_r($data);
```

```
[refrain:44203-73402]
[ar:]
[ti:]
[total:175177]
[17090,4180]<0,228,0>在<228,228,0>没<456,456,0>风<912,228,0>的<1140,380,0>地<1520,532,0>方<2052,228,0>找<2280,456,0>太<2736,1444,0>阳
[24456,5243]<0,228,0>在<228,228,0>你<456,456,0>冷<912,228,0>的<1140,456,0>地<1596,456,0>方<2052,456,0>做<2508,456,0>暖<2964,2279,0>阳
[31832,1824]<0,228,0>人<228,228,0>事<456,228,0>纷<684,1140,0>纷
[34602,2622]<0,228,0>你<228,570,0>总<798,456,0>太<1254,342,0>天<1596,1026,0>真
[38924,1595]<0,228,0>往<228,228,0>后<456,228,0>的<684,228,0>余<925,670,0>生
```

解决php内存分配不足的问题:Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in

PHP网站管理员 Published the article • 0 comments • 442 views • 2018-10-17 12:33 • 来自相关话题

解决php内存分配不足的问题:Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in


### 背景

通常我们在执行php脚本的时候会遇到分配的内存被耗尽,出现内存分配不足的问题,程序无法继续运行下去
如果需要解决这个问题的话,我们需要修改```php.ini```中```memory_limit```的数值,默认是```128M```
```
Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M
```

PHP Fatal error: Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in /mnt/api-site/vendor/nikic/php-parser/lib/PhpParser/Lexer.php on line 280


### 解决方案

```bash
php --ini # 查看php.ini的位置

Configuration File (php.ini) Path: /usr/local/php/etc
Loaded Configuration File: /usr/local/php/etc/php.ini
Scan for additional .ini files in: /usr/local/php/conf.d
Additional .ini files parsed: /usr/local/php/conf.d/002-zendguardloader.ini

# 然后
vim /usr/local/php/etc/php.ini

# find the flag memory_limit
memory_limit = 526M # 修改为这个,如果不够,可以分配更多,1024M, 2048M等等
``` 查看全部

解决php内存分配不足的问题:Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in


### 背景

通常我们在执行php脚本的时候会遇到分配的内存被耗尽,出现内存分配不足的问题,程序无法继续运行下去
如果需要解决这个问题的话,我们需要修改```php.ini```中```memory_limit```的数值,默认是```128M```
```
Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M
```

PHP Fatal error: Allowed memory size of 14680064 bytes exhausted (tried to allocate 20480 bytes) in /mnt/api-site/vendor/nikic/php-parser/lib/PhpParser/Lexer.php on line 280


### 解决方案

```bash
php --ini # 查看php.ini的位置

Configuration File (php.ini) Path: /usr/local/php/etc
Loaded Configuration File: /usr/local/php/etc/php.ini
Scan for additional .ini files in: /usr/local/php/conf.d
Additional .ini files parsed: /usr/local/php/conf.d/002-zendguardloader.ini

# 然后
vim /usr/local/php/etc/php.ini

# find the flag memory_limit
memory_limit = 526M # 修改为这个,如果不够,可以分配更多,1024M, 2048M等等
```

php处理excel读取导入导出excel文件

PHP网站管理员 Published the article • 0 comments • 420 views • 2018-10-11 18:21 • 来自相关话题

### php处理excel读取导入导出excel文件

### PHPOffice/PhpSpreadsheet
这是读取和编写excel电子表格的纯php库,支持如下格式:

|Format |Reading| Writing|
|:-|:-|:-|:-|
|Open Document Format/OASIS (.ods)| ✓ |✓|
|Office Open XML (.xlsx) Excel 2007 and above |✓ |✓|
|BIFF 8 (.xls) Excel 97 and above |✓ |✓|
|BIFF 5 (.xls) Excel 95 |✓ | |
|SpreadsheetML (.xml) Excel 2003 |✓ | |
|Gnumeric |✓ | |
|HTML |✓ |✓ |
|SYLK |✓ | |
|CSV |✓ |✓ |
|PDF (using either the TCPDF, Dompdf or mPDF libraries, which need to be installed separately) |✓ | |
### 通过```composer```导入到项目中
```bash
composer require phpoffice/phpspreadsheet
```

### 案例读取文件

```php 查看全部
### php处理excel读取导入导出excel文件

### PHPOffice/PhpSpreadsheet
这是读取和编写excel电子表格的纯php库,支持如下格式:

|Format |Reading| Writing|
|:-|:-|:-|:-|
|Open Document Format/OASIS (.ods)| ✓ |✓|
|Office Open XML (.xlsx) Excel 2007 and above |✓ |✓|
|BIFF 8 (.xls) Excel 97 and above |✓ |✓|
|BIFF 5 (.xls) Excel 95 |✓ | |
|SpreadsheetML (.xml) Excel 2003 |✓ | |
|Gnumeric |✓ | |
|HTML |✓ |✓ |
|SYLK |✓ | |
|CSV |✓ |✓ |
|PDF (using either the TCPDF, Dompdf or mPDF libraries, which need to be installed separately) |✓ | |
### 通过```composer```导入到项目中
```bash
composer require phpoffice/phpspreadsheet
```

### 案例读取文件

```php
require_once __DIR__ . '/vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\IOFactory;


$excelReader = IOFactory::createReader('Xlsx'); ·// 设置reader类型 xlsx
$sheet = $excelReader->load('demo.xlsx'); // 加载文件
$activeSheet = $sheet->getActiveSheet(); // 获取活跃的sheet
foreach ($activeSheet->getRowIterator() as $row) { // 迭代每一行
$cellIterator = $row->getCellIterator(); // 获取该行,列的迭代器
$cellIterator->setIterateOnlyExistingCells(FALSE);

foreach ($cellIterator as $cell) { // 迭代该行每一列
echo $cell->getValue(), PHP_EOL; // 获取行列所在位置的值
}
}
```

### 写文件,向excel文件中第一行第一列写入Hello World !
```php

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');

$writer = new Xlsx($spreadsheet);
$writer->save('hello-world.xlsx');
```

### 参考

- [github开源项目地址](https://github.com/PHPOffice/PhpSpreadsheet)
- [官方文档](https://phpspreadsheet.readthedocs.io/en/develop/)


php composer update mmap() cannot allocate memory

PHP网站管理员 Published the article • 0 comments • 1283 views • 2018-07-01 21:36 • 来自相关话题

## 背景

php项目执行composer update,出现如下错误:

## 错误输出

```bash
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Loading composer repositories with package information
Updating dependencies (including require-dev)

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory
PHP Fatal error: Out of memory (allocated 816848896) (tried to allocate 33554440 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 65

Fatal error: Out of memory (allocated 816848896) (tried to allocate 33554440 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 65
```

## 解决方案

```bash
apt-get update
apt-get upgrade

reboot
```

重启服务器 查看全部
## 背景

php项目执行composer update,出现如下错误:

## 错误输出

```bash
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Loading composer repositories with package information
Updating dependencies (including require-dev)

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory
PHP Fatal error: Out of memory (allocated 816848896) (tried to allocate 33554440 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 65

Fatal error: Out of memory (allocated 816848896) (tried to allocate 33554440 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 65
```

## 解决方案

```bash
apt-get update
apt-get upgrade

reboot
```

重启服务器

聊聊php的进程

PHP网站管理员 Published the article • 0 comments • 287 views • 2018-06-29 11:27 • 来自相关话题

# 聊聊php的进程

php是当进程执行的,php处理多并发的问题是主要是依赖服务器或者是PHP-FPM的多进程或者进程的复用,PHP实现多进程意义重大,处理大量数据或者后台守护程序是尤为重要。

## ```pcntl_fork``` 实现php多进程

需要加载```pcntl```扩展,而且这个扩展只能在linux环境先编译。

```pcntl_fork()```可以在当前进程,当前位置产生一个子进程,这个函数创建一个子进程后,子进程会继承父进程的上下文,和父进程一样,从```pcntl_fork()```的位置继续往下执行,
只是```pcntl_fork()```的返回值不同,由此,我们可以区分这个是父进程还是子进程,处理不同的逻辑。

- 由于系统初始进程init进程的```pid = 1```,所以父进程的返回值是大于1的
- 子进程返回值固定为0
- 如果```pcntl_fork()```返回值为-1时,说明fork失败了,当然也不会有子进程的存在。


## 代码实例

```php 查看全部

# 聊聊php的进程

php是当进程执行的,php处理多并发的问题是主要是依赖服务器或者是PHP-FPM的多进程或者进程的复用,PHP实现多进程意义重大,处理大量数据或者后台守护程序是尤为重要。

## ```pcntl_fork``` 实现php多进程

需要加载```pcntl```扩展,而且这个扩展只能在linux环境先编译。

```pcntl_fork()```可以在当前进程,当前位置产生一个子进程,这个函数创建一个子进程后,子进程会继承父进程的上下文,和父进程一样,从```pcntl_fork()```的位置继续往下执行,
只是```pcntl_fork()```的返回值不同,由此,我们可以区分这个是父进程还是子进程,处理不同的逻辑。

- 由于系统初始进程init进程的```pid = 1```,所以父进程的返回值是大于1的
- 子进程返回值固定为0
- 如果```pcntl_fork()```返回值为-1时,说明fork失败了,当然也不会有子进程的存在。


## 代码实例

```php

$ppid = posix_getpid();
$pid = pcntl_fork();

if ($pid == -1) {
echo 'fork fail', PHP_EOL;
} else if ($pid > 0) {
cli_set_process_title('php current pid:' . $pid);
echo 'fork success', PHP_EOL;
sleep(30);
} else {
$cpid = posix_getpid();
cli_set_process_title("php ppid: {$ppid}, children pid: {$cpid}.");
sleep(30);
}
```

## 函数介绍

- ```pcntl_fork()``` 创建一个子进程
- ```posix_getpid()``` 获取当前进程的pid
- ```cli_set_process_title($string)``` 为当前进程设置一个名称
- ```pcntl_signal(int $signo , callback $handler)```安装一个信号处理器, $signo是待处理的信号常量,callback是其处理函数
- ```pcntl_signal_dispatch()``` 调用每个等待信号通过pcntl_signal()安装的处理器
- ```posix_kill(int $pid , int $sig)``` 通过向子进程发送一个信号来操作子进程,如发送一个终止信号来结束子进程。
- ```pcntl_waitpid (int $pid , int &$status [, int $options = 0 ])``` 等待或者返回fork的子进程状态,如果子进程在此函数调用时已经退出(俗称僵尸进程),此函数
将立刻返回并且释放所有系统资源,此方法可避免子进程变成僵尸进程,造成系统资源你的浪费。

## 如何管理子进程 (信号)

> 在计算机科学中,信号是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。

这种异步通知机制就是```信号```。

### 分发信号处理器

我们通过父进程接收子进程传来的信号,判断子进程的状态,从而对子进程进行管理。
在父进程中使用```pcntl_signal()```和```pcntl_signal_dispatch```来给各自子进程安装信号处理器。

### 常见的信号

- SIGCHLD 子进程退出成为僵尸进程会向父进程发送这个信号
- SIGHUP 进程挂起
- SIGTEM 进程终止

执行下面的命令,我们可以看到全部的信号
```bash
root@ubuntu:~# kill -l
```

```text
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
```

安装好了信号处理器之后,一旦子进程有相应的信号返回给父进程,父进程就可以调用相应的callback函数对子进程进行处理。


PHP Composer 以及PSR规范

PHP网站管理员 Published the article • 0 comments • 1100 views • 2018-06-27 10:10 • 来自相关话题

## 背景说明

随着项目代码量的不断增加,以及一些库的依赖,我们不得不引入包的管理,来解决不易管理、阅读、模块化等问题。
三方库优秀,而且很多人在维护,功能对接也方便,我们没有必要在这个一个常用的功能上花费时间来封装或者造轮子,
很多人在自己的项目中都实践过,出现了问题,反应的issue也很快会被解决掉,功能也不断在完善。
一直强调,站在巨人的肩膀上,我们会走的更远,也许我们自己撸出来的代码难等大雅之堂,无法比拟,
把重心放在自己的核心产品和功能时间上,学会借鉴学习和使用,降低自己的开发成本。
也许有人会觉得我使用三方库可能会造成性能上的影响,有些功能我根本用不到。项目中代码有很多无用的代码,导致文件加载过慢,
其实不用担心, ```opcache```可以将php脚本预编译到共享内存中来提升php的性能。

## php Composer psr-4 autoload

Composer 是php用来管理依赖关系的工具,可以在项目中声明外部依赖的工具库,Composer会帮你安装这些依赖的库文件
psr-4 是一种代码规范,能够实现package的自动加载,规范了如何从文件路径自动加载类,同时也规范了自动加载文件的位置

## 自动加载

我们在支持Composer的项目中,只需引入这个文件,加上下面这段php的代码,就可以得到自动加载的支持了
```php 查看全部
## 背景说明

随着项目代码量的不断增加,以及一些库的依赖,我们不得不引入包的管理,来解决不易管理、阅读、模块化等问题。
三方库优秀,而且很多人在维护,功能对接也方便,我们没有必要在这个一个常用的功能上花费时间来封装或者造轮子,
很多人在自己的项目中都实践过,出现了问题,反应的issue也很快会被解决掉,功能也不断在完善。
一直强调,站在巨人的肩膀上,我们会走的更远,也许我们自己撸出来的代码难等大雅之堂,无法比拟,
把重心放在自己的核心产品和功能时间上,学会借鉴学习和使用,降低自己的开发成本。
也许有人会觉得我使用三方库可能会造成性能上的影响,有些功能我根本用不到。项目中代码有很多无用的代码,导致文件加载过慢,
其实不用担心, ```opcache```可以将php脚本预编译到共享内存中来提升php的性能。

## php Composer psr-4 autoload

Composer 是php用来管理依赖关系的工具,可以在项目中声明外部依赖的工具库,Composer会帮你安装这些依赖的库文件
psr-4 是一种代码规范,能够实现package的自动加载,规范了如何从文件路径自动加载类,同时也规范了自动加载文件的位置

## 自动加载

我们在支持Composer的项目中,只需引入这个文件,加上下面这段php的代码,就可以得到自动加载的支持了
```php

require_once __DIR __ . '/vendor/autoload.php';

```

## composer.json

```json
{
"autoload": {
"psr-4": {
"Work\\": "src/"
},
"psr-0": {
"Vendor_Namespace_": "src/"
}
}
}
```
Composer 将注册一个 PSR-4 autoloader 到 Work 命名空间, PSR-0 则支持```_```,自动转化为目录结构

### classmap

不遵循PSR-0/4规范的类库,

### files

明确的指定文件加载


## 额外的

### repositories 自定义资源包库

#### type
- composer Composer 类型的资源库,是一个简单的网络服务器上的
- vcs git、svn、hg等
- pear 从pear上获取资源
- package 内联一个```composer.json```对象


## scripts

Composer 允许你在安装过程中的各个阶段挂接脚本。

### [详细流程](http://docs.phpcomposer.com/articles/scripts.html)

### 典型的命令,composer安装时

- post-install-cmd ```composer install```执行之后触发
- post-update-cmd ```composer update```执行之后触发

### 自定义脚本demo

```json
{
"scripts": {
"post-update-cmd": "MyVendor\\MyClass::postUpdate",
"post-package-install": [
"MyVendor\\MyClass::postPackageInstall"
],
"post-install-cmd": [
"MyVendor\\MyClass::warmCache",
"phpunit -c app/",
"find vendor -type d -name .git -exec rm -rf '{}' \\;"
]
}
}
```

```php

namespace MyVendor;

use Composer\Script\Event;

class MyClass
{
public static function postUpdate(Event $event)
{
$composer = $event->getComposer();
// do stuff
}

public static function postPackageInstall(Event $event)
{
$installedPackage = $event->getOperation()->getPackage();
// do stuff
}

public static function warmCache(Event $event)
{
// make cache toasty
}
}
```

不然看出执行的脚本可以是一个类中的静态方法,当然也可以是一个函数,还可以是一条```shell```命令

我们也可以手动执行一些命令

```bash
composer run-script [--dev] [--no-dev] script
```

## 扩展

顺便了解一下其他的几个代码规范

### PSR

#### psr-0 自动加载

#### psr-1 [基本代码规范](https://www.php-fig.org/psr/psr-1/)

- 文件内只出现 ``` - 只是用```utf-8``` 没有BOM头的php代码 (必须)
- 声明新的类型符,不产生副作用
- 命名空间遵循```autoload```自动加载```psr-0/4```规范(必须)
- 类名驼峰(必须)
- 类中的常量下划线```_```分隔(必须)
- 方法驼峰(必须)


#### psr-2 [代码样式](https://www.php-fig.org/psr/psr-2/)

- 必须遵循psr-1
- 四个空格,而非tab
- 限制每行长度 80或者更少
- namespace 和 use 必须空格
- 类的括号必须独立一行
- 类的方法也一样
- 所有的属性和方法必须在修饰符之前,static在之后
- 关键词之后必须有空格
- 代码流程控制,```{``` 在一行,```}```独立一行
- ```{```之后没有空格,```}```之前没有空格

#### psr-3 [日志接口](https://www.php-fig.org/psr/psr-3/)

- 错误级别```RFC 5424``` (debug, info, notice, warning, error, critical, alert,
emergency)


#### psr-4 [自动加载](https://www.php-fig.org/psr/psr-4/)

相比于 psr-0 规范比较干净 PSR-0规范中下划线```_```会被转化成为目录分割线
上面有详细的介绍,这里就不再重复

#### psr-6 [缓存接口](https://www.php-fig.org/psr/psr-6/)


#### psr-7 [http消息接口](https://www.php-fig.org/psr/psr-7/)

#### psr-11 [容器接口](https://www.php-fig.org/psr/psr-11/)

#### psr-13 [超媒体链接](https://www.php-fig.org/psr/psr-13/)

#### psr-15 [http句柄](https://www.php-fig.org/psr/psr-15/)

#### psr-16 [简单缓存](https://www.php-fig.org/psr/psr-16/)


## 收集或者查看过的


- [php规范](https://www.php-fig.org)

- [python入门思维导图](http://naotu.baidu.com/file/a5 ... b2135e)