GVKun编程网logo

提高 PHP 代码质量的 36 计(如何提高php技术)

1

想了解提高PHP代码质量的36计的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于如何提高php技术的相关问题,此外,我们还将为您介绍关于12.21php-fpm的pool12.22php-f

想了解提高 PHP 代码质量的 36 计的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于如何提高php技术的相关问题,此外,我们还将为您介绍关于12.21 php-fpm 的 pool 12.22 php-fpm 慢执行日志 12.23 open_basedir 12.24 php-fpm 进程管理、12.21 php-fpm的pool 12.22 php-fpm慢执行日志 12.23 open_basedir 12.24 php-fpm进程管理、12.21 php-fpm的pool12.22 php-fpm慢执行日志12.23 open_basedir12.24 php-fpm进程管理、5、PHP-将浮点数转为整数 php 浮点数比较 php 浮点数精度 php 浮点数格式的新知识。

本文目录一览:

提高 PHP 代码质量的 36 计(如何提高php技术)

提高 PHP 代码质量的 36 计(如何提高php技术)

1. 不要使用相对路径

常常会看到:

?

1

require_once(''../../lib/some_class.php'');

该方法有很多缺点:

它首先查找指定的 php 包含路径,然后查找当前目录.

因此会检查过多路径.

如果该脚本被另一目录的脚本包含,它的基本目录变成了另一脚本所在的目录.

另一问题,当定时任务运行该脚本,它的上级目录可能就不是工作目录了.

因此最佳选择是使用绝对路径:

?

1

2

3

4

define(''ROOT'' ''/var/www/project/'');

require_once(ROOT . ''../../lib/some_class.php'');

 

//rest of the code

我们定义了一个绝对路径,值被写死了。我们还可以改进它。路径 /var/www/project 也可能会改变,那么我们每次都要改变它吗?不是的,我们可以使用__FILE__常量,如:

?

1

2

3

4

5

6

7

//suppose your script is /var/www/project/index.php

//Then __FILE__ will always have that full path.

 

define(''ROOT'' pathinfo(__FILE__, PATHINFO_DIRNAME));

require_once(ROOT . ''../../lib/some_class.php'');

 

//rest of the code

现在,无论你移到哪个目录,如移到一个外网的服务器上,代码无须更改便可正确运行.

2. 不要直接使用 require, include, include_once, required_once

可以在脚本头部引入多个文件,像类库,工具文件和助手函数等,如:

?

1

2

3

require_once(''lib/Database.php'');

require_once(''lib/Mail.php'');

require_once(''helpers/utitlity_functions.php'');

这种用法相当原始。应该更灵活点。应编写个助手函数包含文件。例如:

?

1

2

3

4

5

6

7

8

9

function load_class($class_name)

{

    //path to the class file

    $path = ROOT . ''/lib/'' $class_name ''.php'');

    require_once$path );

}

 

load_class(''Database'');

load_class(''Mail'');

有什么不一样吗?该代码更具可读性.

將来你可以按需扩展该函数,如:

?

1

2

3

4

5

6

7

8

9

10

function load_class($class_name)

{

    //path to the class file

    $path = ROOT . ''/lib/'' $class_name ''.php'');

 

    if(file_exists($path))

    {

        require_once$path );

    }

}

还可做得更多:

为同样文件查找多个目录

能很容易的改变放置类文件的目录,无须在代码各处一一修改

可使用类似的函数加载文件,如 html 内容.

3. 为应用保留调试代码

在开发环境中,我们打印数据库查询语句,转存有问题的变量值,而一旦问题解决,我们注释或删除它们。然而更好的做法是保留调试代码.

在开发环境中,你可以:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

define(''ENVIRONMENT'' ''development'');

 

if(! $db->query( $query )

{

    if(ENVIRONMENT == ''development'')

    {

        echo "$query failed";

    }

    else

    {

        echo "Database error. Please contact administrator";

    }

}

在服务器中,你可以:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

define(''ENVIRONMENT'' ''production'');

 

if(! $db->query( $query )

{

    if(ENVIRONMENT == ''development'')

    {

        echo "$query failed";

    }

    else

    {

        echo "Database error. Please contact administrator";

    }

}

4. 使用可跨平台的函数执行命令

system, exec, passthru, shell_exec 这 4 个函数可用于执行系统命令。每个的行为都有细微差别。问题在于,当在共享主机中,某些函数可能被选择性的禁用。大多数新手趋于每次首先检查哪个函数可用,然而再使用它.

更好的方案是封成函数一个可跨平台的函数.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

/**

    Method to execute a command in the terminal

    Uses :

 

    1. system

    2. passthru

    3. exec

    4. shell_exec

 

*/

function terminal($command)

{

    //system

    if(function_exists(''system''))

    {

        ob_start();

        system($command $return_var);

        $output = ob_get_contents();

        ob_end_clean();

    }

    //passthru

    else if(function_exists(''passthru''))

    {

        ob_start();

        passthru($command $return_var);

        $output = ob_get_contents();

        ob_end_clean();

    }

 

    //exec

    else if(function_exists(''exec''))

    {

        exec($command $output $return_var);

        $output = implode("n" $output);

    }

 

    //shell_exec

    else if(function_exists(''shell_exec''))

    {

        $output = shell_exec($command) ;

    }

 

    else

    {

        $output ''Command execution not possible on this system'';

        $return_var = 1;

    }

 

    return array(''output'' => $output ''status'' => $return_var);

}

terminal(''ls'');

上面的函数將运行 shell 命令,只要有一个系统函数可用,这保持了代码的一致性.

5. 灵活编写函数

?

1

2

3

4

5

6

function add_to_cart($item_id $qty)

{

    $_SESSION[''cart''][''item_id''] = $qty;

}

 

add_to_cart( ''IPHONE3'' , 2 );

使用上面的函数添加单个项目。而当添加项列表的时候,你要创建另一个函数吗?不用,只要稍加留意不同类型的参数,就会更灵活。如:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

function add_to_cart($item_id $qty)

{

    if(!is_array($item_id))

    {

        $_SESSION[''cart''][''item_id''] = $qty;

    }

 

    else

    {

        foreach($item_id as $i_id => $qty)

        {

            $_SESSION[''cart''][''i_id''] = $qty;

        }

    }

}

 

add_to_cart( ''IPHONE3'' , 2 );

add_to_cart( array(''IPHONE3'' => 2 , ''IPAD'' => 5) );

现在,同个函数可以处理不同类型的输入参数了。可以参照上面的例子重构你的多处代码,使其更智能.

6. 有意忽略 php 关闭标签

我很想知道为什么这么多关于 php 建议的博客文章都没提到这点.

?

1

2

3

4

5

<?php

 

echo "Hello";

 

//Now dont close this tag

这將节约你很多时间。我们举个例子:

一个 super_class.php 文件

?

1

//super extra character after the closing tag

index.php

?

1

2

3

require_once(''super_class.php'');

 

//echo an image or pdf , or set the cookies or session data

这样,你將会得到一个 Headers already send error. 为什么?因为 “super extra character” 已经被输出了。现在你得开始调试啦。这会花费大量时间寻找 super extra 的位置.

因此,养成省略关闭符的习惯:

?

1

2

3

4

5

6

7

8

9

10

<!--?php 

class super_class

{

    function super_function()

    {

        //super code

    }

}

 

//No closing tag</pre-->

这会更好.

7. 在某地方收集所有输入,一次输出给浏览器

这称为输出缓冲,假如说你已在不同的函数输出内容:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

function print_header()

{

    echo "Site Log and Login links";

}

 

function print_footer()

{

    echo "Site was made by me";

}

 

print_header();

for($i = 0 ; $i '';

}

print_footer();

替代方案,在某地方集中收集输出。你可以存储在函数的局部变量中,也可以使用 ob_start 和 ob_end_clean. 如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

function print_header()

{

    $o "Site Log and Login links";

    return $o;

}

 

function print_footer()

{

    $o "Site was made by me";

    return $o;

}

 

echo print_header();

for($i = 0 ; $i '';

}

echo print_footer();

为什么需要输出缓冲:

>> 可以在发送给浏览器前更改输出。如 str_replaces 函数或可能是 preg_replaces 或添加些监控 / 调试的 html 内容.

>> 输出给浏览器的同时又做 php 的处理很糟糕。你应该看到过有些站点的侧边栏或中间出现错误信息。知道为什么会发生吗?因为处理和输出混合了.

8. 发送正确的 mime 类型头信息,如果输出非 html 内容的话.

输出一些 xml.

?

1

2

3

4

5

6

$xml '''';

$xml = "0

";

 

//Send xml data

echo $xml;

工作得不错。但需要一些改进.

?

1

2

3

4

5

6

7

$xml '''';

$xml = "0

";

 

//Send xml data

header("content-type: text/xml");

echo $xml;

注意 header 行。该行告知浏览器发送的是 xml 类型的内容。所以浏览器能正确的处理。很多的 javascript 库也依赖头信息.

类似的有 javascript , css, jpg image, png image:

JavaScript

?

1

2

header("content-type: application/x-javascript");

echo "var a = 10";

CSS

?

1

2

header("content-type: text/css");

echo "#div id { background:#000; }";

9. 为 mysql 连接设置正确的字符编码

曾经遇到过在 mysql 表中设置了 unicode/utf-8 编码,  phpadmin 也能正确显示,但当你获取内容并在页面输出的时候,会出现乱码。这里的问题出在 mysql 连接的字符编码.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

//Attempt to connect to database

$c = mysqli_connect($this->host , $this->username, $this->password);

 

//Check connection validity

if (!$c

{

    die ("Could not connect to the database host: ". mysqli_connect_error());

}

 

//Set the character set of the connection

if(!mysqli_set_charset ( $c ''UTF8'' ))

{

    die(''mysqli_set_charset() failed'');

}

一旦连接数据库,最好设置连接的 characterset. 你的应用如果要支持多语言,这么做是必须的.

10. 使用 htmlentities 设置正确的编码选项

php5.4 前,字符的默认编码是 ISO-8859-1, 不能直接输出如 À â 等.

?

1

$value = htmlentities($this->value , ENT_QUOTES , CHARSET);

php5.4 以后,默认编码为 UTF-8, 这將解决很多问题。但如果你的应用是多语言的, 仍然要留意编码问题,.

11. 不要在应用中使用 gzip 压缩输出,让 apache 处理

考虑过使用 ob_gzhandler 吗?不要那样做。毫无意义. php 只应用来编写应用。不应操心服务器和浏览器的数据传输优化问题.

使用 apache 的 mod_gzip/mod_deflate 模块压缩内容.

12. 使用 json_encode 输出动态 javascript 内容

时常会用 php 输出动态 javascript 内容:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

$images array(

 ''myself.png'' ''friends.png'' ''colleagues.png''

);

 

$js_code '''';

 

foreach($images as $image)

{

$js_code .= "''$image'' ,";

}

 

$js_code ''var images = ['' $js_code '']; '';

 

echo $js_code;

 

//Output is var images = [''myself.png'' ,''friends.png'' ,''colleagues.png'' ,];

更聪明的做法,使用 json_encode:

?

1

2

3

4

5

6

7

8

9

$images array(

 ''myself.png'' ''friends.png'' ''colleagues.png''

);

 

$js_code ''var images = '' . json_encode($images);

 

echo $js_code;

 

//Output is : var images = ["myself.png","friends.png","colleagues.png"]

优雅乎?

13. 写文件前,检查目录写权限

写或保存文件前,确保目录是可写的,假如不可写,输出错误信息。这会节约你很多调试时间. linux 系统中,需要处理权限,目录权限不当会导致很多很多的问题,文件也有可能无法读取等等.

确保你的应用足够智能,输出某些重要信息.

?

1

2

3

4

$contents "All the content";

$file_path "/var/www/project/content.txt";

 

file_put_contents($file_path $contents);

这大体上正确。但有些间接的问题. file_put_contents 可能会由于几个原因失败:

>> 父目录不存在

>> 目录存在,但不可写

>> 文件被写锁住?

所以写文件前做明确的检查更好.

?

1

2

3

4

5

6

7

8

9

10

11

12

$contents "All the content";

$dir ''/var/www/project'';

$file_path $dir "/content.txt";

 

if(is_writable($dir))

{

    file_put_contents($file_path $contents);

}

else

{

    die("Directory $dir is not writable, or does not exist. Please check");

}

这么做后,你会得到一个文件在何处写及为什么失败的明确信息.

14. 更改应用创建的文件权限

在 linux 环境中,权限问题可能会浪费你很多时间。从今往后,无论何时,当你创建一些文件后,确保使用 chmod 设置正确权限。否则的话,可能文件先是由”php” 用户创建,但你用其它的用户登录工作,系统將会拒绝访问或打开文件,你不得不奋力获取 root 权限, 更改文件的权限等等.

?

1

2

3

4

5

// Read and write for owner, read for everybody else

chmod("/somedir/somefile", 0644);

 

// Everything for owner, read and execute for others

chmod("/somedir/somefile", 0755);

15. 不要依赖 submit 按钮值来检查表单提交行为

?

1

2

3

4

if($_POST[''submit''] == ''Save'')

{

    //Save the things

}

上面大多数情况正确,除了应用是多语言的. ‘Save’ 可能代表其它含义。你怎么区分它们呢。因此,不要依赖于 submit 按钮的值.

?

1

2

3

4

if$_SERVER[''REQUEST_METHOD''] == ''POST'' and isset($_POST[''submit'']) )

{

    //Save the things

}

现在你从 submit 按钮值中解脱出来了.

16. 为函数内总具有相同值的变量定义成静态变量

?

1

2

3

4

5

6

7

8

9

//Delay for some time

function delay()

{

    $sync_delay = get_option(''sync_delay'');

 

    echo "Delaying for $sync_delay seconds...";

    sleep($sync_delay);

    echo "Done ";

}

用静态变量取代:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

//Delay for some time

function delay()

{

    static $sync_delay = null;

 

    if($sync_delay == null)

    {

    $sync_delay = get_option(''sync_delay'');

    }

 

    echo "Delaying for $sync_delay seconds...";

    sleep($sync_delay);

    echo "Done ";

}

17. 不要直接使用 $_SESSION 变量

某些简单例子:

?

1

2

$_SESSION[''username''] = $username;

$username $_SESSION[''username''];

这会导致某些问题。如果在同个域名中运行了多个应用,session 变量可能会冲突。两个不同的应用可能使用同一个 session key. 例如,一个前端门户,和一个后台管理系统使用同一域名.

从现在开始,使用应用相关的 key 和一个包装函数:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

define(''APP_ID'' ''abc_corp_ecommerce'');

 

//Function to get a session variable

function session_get($key)

{

    $k = APP_ID . ''.'' $key;

 

    if(isset($_SESSION[$k]))

    {

        return $_SESSION[$k];

    }

 

    return false;

}

 

//Function set the session variable

function session_set($key $value)

{

    $k = APP_ID . ''.'' $key;

    $_SESSION[$k] = $value;

 

    return true;

}

18. 將工具函数封装到类中

假如你在某文件中定义了很多工具函数:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

function utility_a()

{

    //This function does a utility thing like string processing

}

 

function utility_b()

{

    //This function does nother utility thing like database processing

}

 

function utility_c()

{

    //This function is ...

}

这些函数的使用分散到应用各处。你可能想將他们封装到某个类中:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

class Utility

{

    public static function utility_a()

    {

 

    }

 

    public static function utility_b()

    {

 

    }

 

    public static function utility_c()

    {

 

    }

}

 

//and call them as 

 

$a = Utility::utility_a();

$b = Utility::utility_b();

显而易见的好处是,如果 php 内建有同名的函数,这样可以避免冲突.

另一种看法是,你可以在同个应用中为同个类维护多个版本,而不导致冲突. 这是封装的基本好处,无它.

19. Bunch of silly tips

>> 使用 echo 取代 print

>> 使用 str_replace 取代 preg_replace, 除非你绝对需要

>> 不要使用 short tag

>> 简单字符串用单引号取代双引号

>>head 重定向后记得使用 exit

>> 不要在循环中调用函数

>>isset 比 strlen 快

>> 始中如一的格式化代码

>> 不要删除循环或者 if-else 的括号

不要这样写代码:

?

1

if($a == true) $a_count++;

这绝对 WASTE.

写成:

?

1

2

3

4

if($a == true)

{

    $a_count++;

}

不要尝试省略一些语法来缩短代码。而是让你的逻辑简短.

>> 使用有高亮语法显示的文本编辑器。高亮语法能让你减少错误.

20. 使用 array_map 快速处理数组

比如说你想 trim 数组中的所有元素。新手可能会:

?

1

2

3

4

foreach($arr as $c => $v)

{

    $arr[$c] = trim($v);

}

但使用 array_map 更简单:

?

1

$arr array_map(''trim'' $arr);

这会为 $arr 数组的每个元素都申请调用 trim. 另一个类似的函数是 array_walk. 请查阅文档学习更多技巧.

21. 使用 php filter 验证数据

你肯定曾使用过正则表达式验证 email , ip 地址等。是的,每个人都这么使用。现在,我们想做不同的尝试,称为 filter.

php 的 filter 扩展提供了简单的方式验证和检查输入.

22. 强制类型检查

?

1

2

$amount intval$_GET[''amount''] );

$rate = (int) $_GET[''rate''];

这是个好习惯.

23. 如果需要,使用 profiler 如 xdebug

如果你使用 php 开发大型的应用,php 承担了很多运算量,速度会是一个很重要的指标。使用 profile 帮助优化代码。可使用

xdebug 和 webgrid.

24. 小心处理大数组

对于大的数组和字符串,必须小心处理。常见错误是发生数组拷贝导致内存溢出,抛出 Fatal Error of Memory size 信息:

?

1

2

3

4

5

$db_records_in_array_format//This is a big array holding 1000 rows from a table each having 20 columns , every row is atleast 100 bytes , so total 1000 * 20 * 100 = 2MB

 

$cc $db_records_in_array_format//2MB more

 

some_function($cc); //Another 2MB ?

当导入或导出 csv 文件时,常常会这么做.

不要认为上面的代码会经常因内存限制导致脚本崩溃。对于小的变量是没问题的,但处理大数组的时候就必须避免.

确保通过引用传递,或存储在类变量中:

?

1

2

$a = get_large_array();

pass_to_function(&$a);

这么做后,向函数传递变量引用 (而不是拷贝数组). 查看文档.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

class A

{

    function first()

    {

        $this->a = get_large_array();

        $this->pass_to_function();

    }

 

    function pass_to_function()

    {

        //process $this->a

    }

}

尽快的 unset 它们,让内存得以释放,减轻脚本负担.

25.  由始至终使用单一数据库连接

确保你的脚本由始至终都使用单一的数据库连接。在开始处正确的打开连接,使用它直到结束,最后关闭它。不要像下面这样在函数中打开连接:

?

1

2

3

4

5

6

7

8

9

10

11

function add_to_cart()

{

    $db new Database();

    $db->query("INSERT INTO cart .....");

}

 

function empty_cart()

{

    $db new Database();

    $db->query("DELETE FROM cart .....");

}

使用多个连接是个糟糕的,它们会拖慢应用,因为创建连接需要时间和占用内存.

特定情况使用单例模式,如数据库连接.

26. 避免直接写 SQL, 抽象之

不厌其烦的写了太多如下的语句:

?

1

2

$query "INSERT INTO users(name , email , address , phone) VALUES(''$name'' , ''$email'' , ''$address'' , ''$phone'')";

$db->query($query); //call to mysqli_query()

这不是个建壮的方案。它有些缺点:

>> 每次都手动转义值

>> 验证查询是否正确

>> 查询的错误会花很长时间识别 (除非每次都用 if-else 检查)

>> 很难维护复杂的查询

因此使用函数封装:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

function insert_record($table_name $data)

{

    foreach($data as $key => $value)

    {

    //mysqli_real_escape_string

        $data[$key] = $db->mres($value);

    }

 

    $fields = implode('','' array_keys($data));

    $values "''" . implode("'',''" array_values($data)) . "''";

 

    //Final query

    $query "INSERT INTO {$table}($fields) VALUES($values)";

 

    return $db->query($query);

}

 

$data array(''name'' => $name ''email'' => $email  ''address'' => $address ''phone'' => $phone);

 

insert_record(''users'' $data);

看到了吗?这样会更易读和扩展. record_data 函数小心的处理了转义.

最大的优点是数据被预处理为一个数组,任何语法错误都会被捕获.

该函数应该定义在某个 database 类中,你可以像 $db->insert_record 这样调用.

查看本文,看看怎样让你处理数据库更容易.

类似的也可以编写 update,select,delete 方法。试试吧.

27. 將数据库生成的内容缓存到静态文件中

如果所有的内容都是从数据库获取的,它们应该被缓存。一旦生成了,就將它们保存在临时文件中。下次请求该页面时,可直接从缓存中取,不用再查数据库.

好处:

>> 节约 php 处理页面的时间,执行更快

>> 更少的数据库查询意味着更少的 mysql 连接开销

28. 在数据库中保存 session

基于文件的 session 策略会有很多限制。使用基于文件的 session 不能扩展到集群中,因为 session 保存在单个服务器中。但数据库可被多个服务器访问,这样就可以解决问题.

在数据库中保存 session 数据,还有更多好处:

>> 处理 username 重复登录问题。同个 username 不能在两个地方同时登录.

>> 能更准备的查询在线用户状态.

29. 避免使用全局变量

>> 使用 defines/constants

>> 使用函数获取值

>> 使用类并通过 $this 访问

30. 在 head 中使用 base 标签

没听说过?请看下面:

?

1

<img alt="" data-original="happy.jpg" />

base 标签非常有用。假设你的应用分成几个子目录,它们都要包括相同的导航菜单.

www.domain.com/store/home.php

www.domain.com/store/products/ipad.php

在首页中,可以写:

?

1

2

<a href="home.php">Home</a>

<a href="products/ipad.php">Ipad</a>

但在你的 ipad.php 不得不写成:

?

1

2

<span style="color:#333333;font-family:''''Helvetica, Arial, sans-serif'''';"><a href="../home.php">Home</a>

<a href="ipad.php">Ipad</a></span>

因为目录不一样。有这么多不同版本的导航菜单要维护,很糟糕啊.

因此,请使用 base 标签.

?

1

2

3

4

5

6

7

8

<span style="color:#333333;font-family:''''Helvetica, Arial, sans-serif'''';"><head>

<base href="http://www.domain.com/store/">

</head>

<body>

<a href="home.php">Home</a>

<a href="products/ipad.php">Ipad</a>

</body>

</html></span>

现在,这段代码放在应用的各个目录文件中行为都一致.

31. 永远不要將 error_reporting 设为 0

关闭不相的错误报告. E_FATAL 错误是很重要的.

?

1

2

ini_set(''display_errors'', 1);

error_reporting(~E_WARNING & ~E_NOTICE & ~E_STRICT);

32. 注意平台体系结构

integer 在 32 位和 64 位体系结构中长度是不同的。因此某些函数如 strtotime 的行为会不同.

在 64 位的机器中,你会看到如下的输出.

?

1

2

3

4

5

6

7

8

9

$ php -a

Interactive shell

 

php > echo strtotime("0000-00-00 00:00:00");

-62170005200

php > echo strtotime(''1000-01-30'');

-30607739600

php > echo strtotime(''2100-01-30'');

4104930600

但在 32 位机器中,它们將是 bool (false).

33. 不要过分依赖 set_time_limit

如果你想限制最小时间,可以使用下面的脚本:

?

1

2

3

<span style="color:#333333;font-family:''''Helvetica, Arial, sans-serif'''';">set_time_limit(30);

 

//Rest of the code</span>

高枕无忧吗? 注意任何外部的执行,如系统调用,socket 操作,数据库操作等,就不在 set_time_limits 的控制之下.

因此,就算数据库花费了很多时间查询,脚本也不会停止执行。视情况而定.

34. 使用扩展库

一些例子:

>>mPDF — 能通过 html 生成 pdf 文档

>>PHPExcel — 读写 excel

>>PhpMailer — 轻松处理发送包含附近的邮件

>>pChart — 使用 php 生成报表

使用开源库完成复杂任务,如生成 pdf, ms-excel 文件,报表等.

35. 使用 MVC 框架

是时候使用像 codeigniter 这样的 MVC 框架了. MVC 框架并不强迫你写面向对象的代码。它们仅將 php 代码与 html 分离.

>> 明确区分 php 和 html 代码。在团队协作中有好处,设计师和程序员可以同时工作.

>> 面向对象设计的函数能让你更容易维护

>> 内建函数完成了很多工作,你不需要重复编写

>> 开发大的应用是必须的

>> 很多建议,技巧和 hack 已被框架实现了

36. 时常看看 phpbench

phpbench 提供了些 php 基本操作的基准测试结果,它展示了一些徽小的语法变化是怎样导致巨大差异的.

查看 php 站点的评论,有问题到 IRC 提问,时常阅读开源代码,使用 Linux 开发.

英文原文:http://www.binarytides.com/35-techniques-to-enhance-your-php-code/

中文译文:http://www.techug.com/techniques-to-enhance-your

12.21 php-fpm 的 pool 12.22 php-fpm 慢执行日志 12.23 open_basedir 12.24 php-fpm 进程管理

12.21 php-fpm 的 pool 12.22 php-fpm 慢执行日志 12.23 open_basedir 12.24 php-fpm 进程管理

12.21 php-fpm 的 pool

每一个站点使用独立的 pool (池子), 好处是当其中一个 php 502 了 (php 资源耗尽了), 也不会影响到其他网站.

vim /usr/local/php-fpm/etc/php-fpm.conf //在[global]部分增加如下, 并删除默认的 www 的pool

include = etc/php-fpm.d/*.conf



/usr/local/php-fpm/sbin/php-fpm -t   //测试php-fpm.conf语法错误

mkdir /usr/local/php-fpm/etc/php-fpm.d/
cd /usr/local/php-fpm/etc/php-fpm.d/

vim www.conf //内容如下

[www]
listen = /tmp/php-fcgi.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

vim test.conf //内容如下
[test]
listen = /tmp/www.sock
listen.mode=666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

测试:

service php-fpm restart   // 或者 /etc/init.d/php-fpm restart
ps aux | grep php   //可以看到有多个pool

可以把 vim /usr/local/nginx/conf/vhost/test.com.conf 的 sock 给改掉成 test.sock

/usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx -s reload

访问网站 测试是否正确解析 php : http://www.test.com/1.php

12.22 php-fpm 慢执行日志

慢执行日志,我们用来分析 php 网站为什么访问慢

vim /usr/local/php-fpm/etc/php-fpm.d/test.conf //加入如下内容
request_slowlog_timeout = 2    //超过2秒钟,我就要记录日志  一般情况写成2秒, 1秒太短了点
slowlog = /usr/local/php-fpm/var/log/test-slow.log

/usr/local/php-fpm/sbin/php-fpm -t 
/etc/init.d/php-fpm reload   //重新加载php 配置文件

看见产生了慢执行日志

 vim /data/wwwroot/test.com/sleep.php//写入如下内容
 
?php  
echo “test slow log”;
sleep(3);
echo “done”;
?>


curl -x127.0.0.1:80 www.test.com/sleep.php   测试报错:


编辑 vim /usr/local/php-fpm/etc/php.ini   

打开 

/etc/init.d/php-fpm reload

查看到语法错误


修改  vim /data/wwwroot/test.com/sleep.php  // 用英文的双引号和分号

<?php
echo "test slow log";
sleep(3);
echo "done";
?>

 curl -x127.0.0.1:80 www.test.com/sleep.php



 cat /usr/local/php-fpm/var/log/www-slow.log   //查看慢执行日志

会告诉你哪个php文件慢,  而且会告诉你php文件第三行慢

12.23 open_basedir

安全选项 open_basedir, 主要用来定义 限制网站能访问的目录 (限制 php 在指定的目录里活动)

vim /usr/local/php-fpm/etc/php-fpm.d/test.conf //加入如下内容
php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp

创建测试php脚本,进行测试
etc/init.d/php-fpm restart

curl -x127.0.0.1:80 www.test.com/1.php -I

再次更改test.conf,修改路径,再次测试
故意改错成  php_admin_value[open_basedir]=/data/wwwroot/111test.com:/tmp

配置错误日志
vim /usr/local/php-fpm/etc/php.ini

display_errors=off //是否在页面上显示错误, 如果否, 需定义log_errors
log_errors=on //错误日志是否开启  如果是, 则需定义 log_errors 和  error_log , error_reporting
error_log = /usr/local/php-fpm/var/log/php_errors.log   //定义错误日志的路径
error_reporting=E_ALL & ~E_NOTICE  //错误日志记录的级别, 生产环境用 E_ALL & ~E_NOTICE(阿铭说) , 我看到默认生产环境配置文件 用  E_ALL & ~E_DEPRECATED & ~E_STRICT

创建错误日志文件并设置权限
touch  /usr/local/php-fpm/var/log/php_errors.log
chmod 666   /usr/local/php-fpm/var/log/php_errors.log

/etc/init.d/php-fpm restart

再次测试


查看错误日志

tail -f /usr/local/php-fpm/var/log

12.24 php-fpm 进程管理

/usr/local/php-fpm/etc/php.ini , 注释用;号,用 #号不太对,如;pm = dynamic

动态进程管理,先一开始启动20个进程, 根据需求(访问量)自动生成进程, 服务器闲也会自动销毁,
也可以是static, static只有 pm.max_children有效, start_servers /min_spare_servers /max_spare_servers 都会失效

pm = dynamic  //动态进程管理
pm.max_children = 50 //最大子进程数,ps aux可以查看
pm.start_servers = 20 //启动服务时会启动的进程数
pm.min_spare_servers = 5 //定义在空闲时段,子进程数的最少数量,如果达到这个数值时,php-fpm服务会自动派生新的子进程。
pm.max_spare_servers = 35 //定义在空闲时段,子进程数的最大值,如果高于这个数值就开始清理空闲的子进程。
pm.max_requests = 500  //定义一个子进程最多处理的请求数,也就是说在一个php-fpm的子进程最多可以处理这么多请求,当达到这个数值时,它会自动退出。
rlimit_files = 1024   //设置文件打开描述符的rlimit限制. 默认值: 系统定义值 系统默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。

12.21 php-fpm的pool 12.22 php-fpm慢执行日志 12.23 open_basedir 12.24 php-fpm进程管理

12.21 php-fpm的pool 12.22 php-fpm慢执行日志 12.23 open_basedir 12.24 php-fpm进程管理

12.21 php-fpm的pool

为了避免因多站点使用同一个pool时因一个站点故障导致pool出问题,进而影响使用同一个pool的其他站点的正常运行,要对每个站点配置一个单独的pool。

为php-fpm增加pool

[root@cham002 cham.com]# cd /usr/local/php-fpm/etc/
[root@cham002 etc]# ls
pear.conf  php-fpm.conf  php-fpm.conf.default  php.ini
[root@cham002 etc]# cat php-fpm.conf
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
[www]
#listen = /tmp/php-fcgi.sock
listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
[root@cham002 etc]# vi !$
vi php-fpm.conf

[champin.com]
#listen = /tmp/champin.sock
listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

语法检测:

[root@cham002 etc]# /usr/local/php-fpm/sbin/php-fpm -t
[09-Jan-2018 00:36:35] ERROR: [pool champin.com] unable to set listen address as it''s already used in another pool ''www''
[09-Jan-2018 00:36:35] ERROR: failed to post process the configuration
[09-Jan-2018 00:36:35] ERROR: FPM initialization failed

原因是我以为名字不对,后来换了名字还是不行,仔细看配置文件发现原因

[root@cham002 etc]# /usr/local/php-fpm/sbin/php-fpm -t
[09-Jan-2018 00:45:20] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful
[root@cham002 etc]# /etc/init.d/php-fpm reload
Reload service php-fpm  done

[root@cham002 etc]# ps aux |grep php-fpm
root      6251  0.5  0.4 227212  4980 ?        Ss   00:49   0:00 php-fpm: master process (/usr/local/php-fpm/etc/php-fpm.conf)
php-fpm   6252  0.0  0.4 227152  4712 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6253  0.0  0.4 227152  4712 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6254  0.0  0.4 227152  4712 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6255  0.0  0.4 227152  4712 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6256  0.0  0.4 227152  4716 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6257  0.0  0.4 227152  4716 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6258  0.0  0.4 227152  4716 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6259  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6260  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6261  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6262  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6263  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6264  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6265  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6266  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6267  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6268  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6269  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6270  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6271  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool www
php-fpm   6272  0.0  0.4 227152  4716 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6273  0.0  0.4 227152  4716 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6274  0.0  0.4 227152  4716 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6275  0.0  0.4 227152  4720 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6276  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6277  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6278  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6279  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6280  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6281  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6282  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6283  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6284  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6285  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6286  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6287  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6288  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6289  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6290  0.0  0.4 227152  4724 ?        S    00:49   0:00 php-fpm: pool champ
php-fpm   6291  0.0  0.4 227152  4728 ?        S    00:49   0:00 php-fpm: pool champ
root      6293  1.0  0.0 112680   976 pts/1    R+   00:49   0:00 grep --color=auto php-fpm

为站点配置pool

[root@cham002 etc]# cd /usr/local/nginx/conf/vhost/
[root@cham002 vhost]# ls
aaa.com.conf  load.conf  proxy.conf  ssl.conf  test.com.conf
[root@cham002 vhost]# vim aaa.com.conf 

server
{
    listen 80 default_server;
    server_name aaa.com;
    index index.html index.htm index.php;
    root /data/wwwroot/default;
 location ~ \.php$
    {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/champ.sock;
       #fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/default$fastcgi_script_name;
    }

}

说明: 把fastcgi_pass地址改为和php-fpm.conf中一样的地址就可以。

 

添加php-fpm.conf子配置文件

为了便于管理,可以将php-fpm中的每个pool单独进行管理。进行如下操作,添加php-fpm子配置文件:

[root@cham002 vhost]# cd /usr/local/php-fpm/etc/
[root@cham002 etc]# vim php-fpm.conf
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
include = etc/php-fpm.d/*.conf

说明: 在全局变量版块添加参数“include = etc/php-fpm.d/*.conf”。然后可以清除php-fpm配置文件中其他参数,再到php-fpm.d目录下进行单独设置。

[root@cham002 vhost]# cd /usr/local/php-fpm/etc/
[root@cham002 etc]# mkdir php-fpm.d
[root@cham002 etc]# cd php-fpm.d/
[root@cham002 php-fpm.d]# vim www.conf
[www]
listen = /tmp/php-fcgi.sock
#listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
[root@cham002 php-fpm.d]# ls
www.conf

[root@cham002 php-fpm.d]# vim champ.conf
[champ]
listen = /tmp/champ.sock
#listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
[root@cham002 php-fpm.d]# ls
champ.conf  www.conf


[root@cham002 php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm -t
[09-Jan-2018 01:20:26] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[root@cham002 php-fpm.d]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done


[root@cham002 php-fpm.d]# ps aux |grep php-fpm
root      6508  1.5  0.4 227240  4988 ?        Ss   01:26   0:00 php-fpm: master process (/usr/local/php-fpm/etc/php-fpm.conf)
php-fpm   6509  0.0  0.4 227180  4720 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6510  0.0  0.4 227180  4720 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6511  0.0  0.4 227180  4720 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6512  0.0  0.4 227180  4720 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6513  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6514  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6515  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6516  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6517  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6518  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6519  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6520  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6521  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6522  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6523  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6524  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6525  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6526  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6527  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6528  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool champ
php-fpm   6529  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6530  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6531  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6532  0.0  0.4 227180  4724 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6533  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6534  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6535  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6536  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6537  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6538  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6539  0.0  0.4 227180  4728 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6540  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6541  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6542  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6543  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6544  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6545  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6546  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6547  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
php-fpm   6548  0.0  0.4 227180  4732 ?        S    01:26   0:00 php-fpm: pool www
root      6550  0.0  0.0 112680   976 pts/1    R+   01:26   0:00 grep --color=auto php-fpm


配置完成后使用ps查看php-fpm进程信息。

12.22 php-fpm的慢执行日志

开启慢执行日志:

[root@cham002 php-fpm.d]# vim www.conf 

[www]
listen = /tmp/php-fcgi.sock
#listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
request_slowlog_timeout = 1
#当请求超过1秒开始记录日志
slowlog = /usr/local/php-fpm/var/log/www-slow.log
#日志存放路径

试验

在使用www pool的站点添加文件: 

[root@cham002 php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm -t
[09-Jan-2018 01:31:57] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[root@cham002 php-fpm.d]# /etc/init.d/php-fpm reload
Reload service php-fpm  done

[root@cham002 php-fpm.d]# ls /usr/local/php-fpm/var/log/www-slow.log
/usr/local/php-fpm/var/log/www-slow.log

[root@cham002 php-fpm.d]# vim /data/wwwroot/test.com/sleep.php

<?php
 echo "test slow log";
sleep(2);
echo "done";
?>

 试一下

[root@cham002 php-fpm.d]# curl -x127.0.0.1:80 test.com/sleep.php
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.12.1</center>
</body>
</html>
[root@cham002 php-fpm.d]# cat /usr/local/nginx/conf/vhost/test.com.conf 
server
{
    listen 80;
#报502的错误,查看配置文件,发现监听的地址被注重掉了
[root@cham002 php-fpm.d]# cat /usr/local/nginx/conf/vhost/test.com.conf 
server
{
    listen 80;
    server_name test.com test2.com test3.com;
    index index.html index.htm index.php;
    root /data/wwwroot/test.com;
    if ($host != ''test.com'' ) {
        rewrite  ^/(.*)$  http://test.com/$1  permanent;
    }
   # location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
   # {
   #       expires      7d;
   #       access_log off;
   # }
location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$
{
    expires 7d;
    valid_referers none blocked server_names  *.test.com ;
    if ($invalid_referer) {
        return 403;
    }
    access_log off;
}


    location ~ .*\.(js|css)$
    {
          expires      12h;
          access_log off;
    }
    location /admin/
    {
       allow 127.0.0.1;
       allow 192.168.230.135;
       deny all;
    }

    location ~ .*(upload|image)/.*\.php$
    {
        deny all;
    }
    
    if ($http_user_agent ~ ''Spider/3.0|YoudaoBot|Tomato'')
    {
      return 403;
    }

    location ~ \.php$
    {
        include fastcgi_params;
        #fastcgi_pass unix:/tmp/php-fcgi.sock;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/test.com$fastcgi_script_name;
    }



    access_log /tmp/test.com.log cham;
}

[root@cham002 php-fpm.d]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@cham002 php-fpm.d]#  /usr/local/nginx/sbin/nginx -s reload


[root@cham002 php-fpm.d]# curl -x127.0.0.1:80 test.com/sleep.php
test slow logdone

Reload service php-fpm  done


[root@cham002 php-fpm.d]# cat /usr/local/php-fpm/var/log/www-slow.log 
##查看日志!!!!!
[09-Jan-2018 01:50:17]  [pool www] pid 6700
script_filename = /data/wwwroot/test.com/sleep.php
[0x00007f98c94b02f8] sleep() /data/wwwroot/test.com/sleep.php:3

日志中表明详细信息

说明:一般会写成2秒,多数php脚本都会超过1秒

 

12.23 php-fpm中指定open_basedir

当一台服务器跑多个站点时,使用open_basedir限定各个站点所能访问的服务器上的目录的范围。在php-fpm服务中,可以针对每个pool设定open _ basedir。

核心配置参数:

[root@cham002 php-fpm.d]# vim www.conf 

[www]
listen = /tmp/php-fcgi.sock
#listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
request_slowlog_timeout = 1
slowlog = /usr/local/php-fpm/var/log/www-slow.log
php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/


[root@cham002 php-fpm.d]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done
[root@cham002 php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Mon, 08 Jan 2018 18:05:28 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

[root@cham002 php-fpm.d]# vi /usr/local/php-fpm/etc/php.ini

[root@cham002 php-fpm.d]# grep error_log /usr/local/php-fpm/etc/php.ini
; server-specific log, STDERR, or a location specified by the error_log
; Set maximum length of log_errors. In error_log information about the source is
;error_log = php_errors.log
;error_log = syslog
error_log = /usr/local/php-fpm/var/log/php_errors.log
; OPcache error_log file name. Empty string assumes "stderr".
;opcache.error_log=
[root@cham002 php-fpm.d]# ls /usr/local/php-fpm/var/log/
php-fpm.log   www-slow.log  
[root@cham002 php-fpm.d]# vim www.conf 故意写错地址
[root@cham002 php-fpm.d]# touch /usr/local/php-fpm/var/log/php_errors.log
[root@cham002 php-fpm.d]# chmod 777 /usr/local/php-fpm/var/log/php_errors.log
[root@cham002 php-fpm.d]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done

[root@cham002 php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php
No input file specified.
[root@cham002 php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.12.1
Date: Mon, 08 Jan 2018 18:17:50 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

[root@cham002 php-fpm.d]# cat /usr/local/php-fpm/var/log/php_errors.log
[08-Jan-2018 18:17:44 UTC] PHP Warning:  Unknown: open_basedir restriction in effect. File(/data/wwwroot/test.com/3.php) is not within the allowed path(s): (/data/wwwroot/etest.com:/tmp/) in Unknown on line 0
[08-Jan-2018 18:17:44 UTC] PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on line 0
[08-Jan-2018 18:17:50 UTC] PHP Warning:  Unknown: open_basedir restriction in effect. File(/data/wwwroot/test.com/3.php) is not within the allowed path(s): (/data/wwwroot/etest.com:/tmp/) in Unknown on line 0
[08-Jan-2018 18:17:50 UTC] PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on line 0

改正之后再来测试
[root@cham002 php-fpm.d]# vim www.conf 

[root@cham002 php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Mon, 08 Jan 2018 18:21:54 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30


 

12.24 php-fpm进程管理

php-fpm中pool配置参数解析:

[root@cham002 php-fpm.d]# cat www.conf 
[www]
listen = /tmp/php-fcgi.sock
#listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
;定义进程启动方式(dynamic表示动态,static表示静态)
;只有此处设置为dynamic,下面的配置才生效
pm.max_children = 50
;最多可启动的子进程数量
pm.start_servers = 20
;设定初始启动的进程数量
pm.min_spare_servers = 5
;表示php-fpm空闲时最少要有几个子进程
pm.max_spare_servers = 35
;表示php-fpm空闲时最多要有几个子进程
pm.max_requests = 500
;表示一个子进程最多可接受多少个请求
rlimit_files = 1024
;表示每个子进程打开的多少个文件句柄
request_slowlog_timeout = 1
;当请求超过1秒开始记录日志
slowlog = /usr/local/php-fpm/var/log/www-slow.log
;日志存放地址
php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/

 

12.21 php-fpm的pool12.22 php-fpm慢执行日志12.23 open_basedir12.24 php-fpm进程管理

12.21 php-fpm的pool12.22 php-fpm慢执行日志12.23 open_basedir12.24 php-fpm进程管理

12.21 php-fpm的pool

知识点

pool 池子,每一个池子都可以监听不同的sock或者是TCP/IP,nginx如果有多个站点,那么每个站点都能去使用一个独立的pool,这样做的好处是,当其中一个php发生错误了(资源不够),所以就有必要让每一个站点使用独立的pool

例如:php程序编写时发生了错误,就会导致整个php资源耗尽,因为pool只支持57个进程,当进程满的时候,如果再有新的请求,将会发现资源被耗尽,就会反馈用户502

增加pool并指定让那个站点使用

配置方法一:

在php-fpm.conf下直接添加一段

[aming.com]
listen = /tmp/aming.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

配置方法二:

使用类似配置vhost的办法,创建目录,单个文件对单个站点(这样的办法看起来不急干净,便于维护) 创建存放的目录

[root@aminglinux-02 vhost]# cd /usr/local/php-fpm/etc/
[root@aminglinux-02 etc]# mkdir php-fpm.d
[root@aminglinux-02 etc]# ls
pear.conf  php-fpm.conf  php-fpm.conf.default  php-fpm.d  php.ini

在php-fpm.conf主配置文件下添加配置,并删除之前的pool的配置;删除前cat一次文件,以便拷贝pool的配置到新的配置文件里

[root@aminglinux-02 etc]# vim php-fpm.conf
include = etc/php-fpm.d/*.conf

在新创建的目录下,创建对应站点的pool

[root@aminglinux-02 php-fpm.d]# pwd
/usr/local/php-fpm/etc/php-fpm.d
[root@aminglinux-02 php-fpm.d]# ls
aming.conf  www.conf

配置好以后,检查语法并重启

[root@aminglinux-02 ~]# /usr/local/php-fpm/sbin/php-fpm -t
[root@aminglinux-02 ~]# /etc/init.d/php-fpm reload
Reload service php-fpm  done

查看新增的pool是否被使用

[root@aminglinux-02 ~]# ps aux |grep php-fpm
root      2723  0.0  0.2 226700  4960 ?        Ss   01:17   0:00 php-fpm: master process (/usr/local/php-fpm/etc/php-fpm.conf)
php-fpm   2724  0.0  0.2 226640  4704 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2725  0.0  0.2 226640  4704 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2726  0.0  0.2 226640  4704 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2727  0.0  0.2 226640  4704 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2728  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2729  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2730  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2731  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2732  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2733  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2734  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2735  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2736  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2737  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2738  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2739  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2740  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2741  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2742  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2743  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool www
php-fpm   2744  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2745  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2746  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2747  0.0  0.2 226640  4708 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2748  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2749  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2750  0.0  0.2 226640  4712 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2751  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2752  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2753  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2754  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2755  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2756  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2757  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2758  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2759  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2760  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2761  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2762  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
php-fpm   2763  0.0  0.2 226640  4716 ?        S    01:17   0:00 php-fpm: pool aming.com
root      2765  0.0  0.0 112664   976 pts/0    R+   01:17   0:00 grep --color=auto php-fpm

发现新增了pool 名字为 aming.com

在nginx里启用

配置新的虚拟主机配置文件

[root@aminglinux-02 vhost]# pwd
/usr/local/nginx/conf/vhost
[root@aminglinux-02 vhost]# vim aaa.com.conf
server
{
    listen 80 default_server;
    server_name aaa.com;
    index index.html index.htm index.php;
    root /data/wwwroot/default;
location ~ \.php$                                    //新增解析php 下面这一整段
    {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/aming.sock;    //指定新添加的pool里面配置的sock
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/default$fastcgi_script_name;  
    }

}

12.22 php-fpm慢执行日志

做 php 的网站,建议使用lnmp,主要原因就是可以去分析慢执行; 查询办法 1、系统负载,可以通过各种工具查,查出是哪个进程导致 2、PHP网站访问慢,通过慢日志

配置方法:

配置pool文件

[root@aminglinux-02 php-fpm.d]# vim www.conf

[www]
listen = /tmp/php-fcgi.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
request_slowlog_timeout = 1   //新增;超过一秒钟记录一次;一般用2秒比较合适,因为很多脚本都会超过1秒
slowlog = /usr/local/php-fpm/var/log/www-slow.log  //新增;日志存放路径

配置完成,检查语法&&重新加载服务

[root@aminglinux-02 php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm -t
[17-Aug-2017 01:48:30] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[root@aminglinux-02 php-fpm.d]# /etc/init.d/php-fpm reload
Reload service php-fpm  don

查看一下是否生成日志文件,是否有内容

[root@aminglinux-02 php-fpm.d]# ls /usr/local/php-fpm/var/log/www-slow.log
/usr/local/php-fpm/var/log/www-slow.log
[root@aminglinux-02 php-fpm.d]# cat !$
cat /usr/local/php-fpm/var/log/www-slow.log

日志文件并没有内容,因为还没有发生超过1秒的php执行的情况

模拟一个慢执行的php

到www pool的所支持的站点下,创建一个慢执行的php

[root@aminglinux-02 test.com]# pwd
/data/wwwroot/test.com
[root@aminglinux-02 test.com]# vim sleep.php
<?php
echo “test slow log”;
sleep(2);
echo “done”;
?>

检查语法&&重新加载服务

[root@aminglinux-02 test.com]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@aminglinux-02 test.com]# /usr/local/nginx/sbin/nginx -s reload

测试

[root@aminglinux-02 test.com]# curl -x127.0.0.1:80 test.com/sleep.php -I
HTTP/1.1 500 Internal Server Error
Server: nginx/1.12.1
Date: Wed, 16 Aug 2017 17:56:11 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

提示500 表示有错

打开在浏览器查看错误信息

[root@aminglinux-02 test.com]# vim /usr/local/php-fpm/etc/php.ini

搜索 display_err ,on 这个配置,将能在浏览器上查看错误信息

[root@aminglinux-02 test.com]# curl -x127.0.0.1:80 test.com/sleep.php
<br />
<b>Parse error</b>:  syntax error, unexpected ''slow'' (T_STRING), expecting '','' or '';'' in <b>/data/wwwroot/test.com/sleep.php</b> on line <b>2</b><br />

提示:解析错误< / b >:语法错误,意外的“慢”(T_STRING),期望“,”或“;在< b > /数据/ wwwroot /test.com/sleep.php < / b > < b > 2行< / b > 检查sleep.php文件

发现里面的标点用的是中文标点,更改后重启配置

再次测试

[root@aminglinux-02 test.com]# curl -x127.0.0.1:80 test.com/sleep.php
test slow logdone

发现会慢2秒才输出结果

这时候可以去查看是否生成了慢日志

[root@aminglinux-02 test.com]# cat /usr/local/php-fpm/var/log/www-slow.log

[17-Aug-2017 02:07:35]  [pool www] pid 3133
script_filename = /data/wwwroot/test.com/sleep.php   //提示:是哪个文件慢
[0x00007ff86b542298] sleep() /data/wwwroot/test.com/sleep.php:3 //提示:是文件里的那一行慢

查看相关的文件

[root@aminglinux-02 test.com]# cat sleep.php
<?php
echo "test slow log";
sleep(2);           // 这一行因为执行了sleep 2 ,将暂停2秒,就是这个导致慢,所以被日志记录
echo "done";
?>

12.23 open_basedir

知识点

因为如果服务器管理多个网站,在php.ini里定义多个open_basedir就不合适了,所以使用针对pool定义对应的open_basedir

配置open_basedir

对www的pool进行配置,在最末行加多一行配置

[root@aminglinux-02 php-fpm.d]# vim www.conf
php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/     如果路径出错,会导致404页面 curl直接连会提示“No input file specified.”

开启错误日志记录

定义错误日志

;error_log = php_errors.log
; Log errors to syslog (Event Log on Windows).
;error_log = syslog
error_log = /usr/local/php-fpm/var/log/php_errors.log   //这一段定义错误日志

定义错误日志的级别

error_reporting = E_ALL  //所有

查看刚更改的路径是否存在

[root@aminglinux-02 php-fpm.d]# grep error_log /usr/local/php-fpm/etc/php.ini
; server-specific log, STDERR, or a location specified by the error_log
; Set maximum length of log_errors. In error_log information about the source is
;error_log = php_errors.log
;error_log = syslog
error_log = /usr/local/php-fpm/var/log/php_errors.log
; OPcache error_log file name. Empty string assumes "stderr".
;opcache.error_log=
[root@aminglinux-02 php-fpm.d]# ls /usr/local/php-fpm/var/log/
php-fpm.log  www-slow.log

为了保证能正常的写入日志,需要进行以下操作 创建好一个错误日志文件

[root@aminglinux-02 php-fpm.d]# touch /usr/local/php-fpm/var/log/php_errors.log

将它的权限设置为777,以便写入

[root@aminglinux-02 php-fpm.d]# chmod 777 !$
chmod 777 /usr/local/php-fpm/var/log/php_errors.log
[root@aminglinux-02 php-fpm.d]# ls -lhtr /usr/local/php-fpm/var/log/
总用量 16K
-rw------- 1 root root  480 8月  17 02:07 www-slow.log
-rw------- 1 root root 9.1K 8月  17 02:07 php-fpm.log
-rwxrwxrwx 1 root root    0 8月  17 02:30 php_errors.log

12.24 php-fpm进程管理

[root@aminglinux-02 php-fpm.d]# cat www.conf
[www]
listen = /tmp/php-fcgi.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic    //表示进程以什么形式启动,dynamic就是动态,动态就是一开始为一个数值,根据需求再自动生成,服务器比较闲的时候还会去销毁,销毁到一定程度还有自动生成
pm.max_children = 50     //最大子进程数,ps aux可以查看
pm.start_servers = 20   //启动服务时会启动的进程数
pm.min_spare_servers = 5   //定义在空闲时段,子进程数的最少数量,如果达到这个数值时,php-fpm服务会自动派生新的子进程。
pm.max_spare_servers = 35   //定义在空闲时段,子进程数的最大值,如果高于这个数值就开始清理空闲的子进程。
pm.max_requests = 500    //定义一个子进程最多处理的请求数,也就是说在一个php-fpm的子进程最多可以处理这么多请求,当达到这个数值时,它会自动退出。
rlimit_files = 1024
request_slowlog_timeout = 1
slowlog = /usr/local/php-fpm/var/log/www-slow.log
php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/

pm = dynamic //表示进程以什么形式启动,dynamic就是动态,动态就是一开始为一个数值,根据需求再自动生成,服务器比较闲的时候还会去销毁,销毁到一定程度还有自动生成;根据下面的设置去进行设定“start_servers ”、“min_spare_servers ”、“max_spare_servers ”、“max_requests ”

==pm 还有一个选择是 static ,一旦选择这个设置,下面的pm的各种设置只会有一个max_children生效==

5、PHP-将浮点数转为整数 php 浮点数比较 php 浮点数精度 php 浮点数格式

5、PHP-将浮点数转为整数 php 浮点数比较 php 浮点数精度 php 浮点数格式

1、使用强制类型转换

首先PHP支持如下所示的数据类型:

<span>1. </span>Integer    (整数)
<span>2. </span>Float      (浮点数)
<span>3. </span>String     (字符串)
<span>4. </span>Boolean    (布尔值)
<span>5. </span>Array      (数组)
<span>6. </span>Object     (对象)
登录后复制

此外还有两个特殊的类型:NULL(空)、resource(资源)。

注:
1. 没有被赋值、已经被重置或者被赋值为特殊值NULL的变量就是NULL类型的变量。
2. 特定的内置函数(例如数据库函数)将返回resource类型的变量。

接着可以使用类似C语言的强制类型转换,例如

<span><?php </span><span>$a</span>=<span>6.66666</span>;
<span>$b</span>=(integer)<span>$a</span>;
<span>echo</span><span>$b</span>;</span>
登录后复制

将输出一个6,直接舍去了小数部分

立即学习“PHP免费学习笔记(深入)”;

2、使用float floor ( float value) 函数

舍去法取整,返回不大于 value 的下一个整数,将 value 的小数部分舍去取整。floor() 返回的类型仍然是 float,因为float 值的范围通常比 integer 要大。

echo <span>floor</span>(<span>4.3</span>);   <span>// 输出4 </span>
echo <span>floor</span>(<span>9.999</span>); <span>// 输出9</span>
登录后复制

3、使用float ceil ( float value) 函数

进一法取整,返回不小于 value 的下一个整数,value 如果有小数部分则进一位。ceil() 返回的类型仍然是 float,因为float 值的范围通常比 integer 要大。

echo <span>ceil</span>(<span>4.3</span>);    <span>// 输出5 </span>
echo <span>ceil</span>(<span>9.999</span>);  <span>// 输出10</span>
登录后复制

4、使用float round ( float val [, int precision])函数

对浮点数进行四舍五入,返回将 val 根据指定精度 precision(十进制小数点后数字的数目)进行四舍五入的结果。precision 也可以是负数或零(默认值)。

echo <span>round</span>(<span>3.4</span>);         <span>// 输出3 </span>
echo <span>round</span>(<span>3.5</span>);         <span>// 输出4 </span>
echo <span>round</span>(<span>3.6</span>);         <span>// 输出4 </span>
echo <span>round</span>(<span>3.6</span>, <span>0</span>);      <span>// 输出4 </span>
echo <span>round</span>(<span>1.95583</span>, <span>2</span>);  <span>// 输出1.96 </span>
echo <span>round</span>(<span>1241757</span>, -<span>3</span>); <span>// 输出1242000 </span>
echo <span>round</span>(<span>5.045</span>, <span>2</span>);    <span>// 输出5.04 </span>
echo <span>round</span>(<span>5.055</span>, <span>2</span>);    <span>// 输出5.06</span>
登录后复制
'').addClass(''pre-numbering'').hide(); $(this).addClass(''has-numbering'').parent().append($numbering); for (i = 1; i '').text(i)); }; $numbering.fadeIn(1700); }); });

以上就介绍了5、PHP-将浮点数转为整数,包括了php,浮点数方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

今天关于提高 PHP 代码质量的 36 计如何提高php技术的介绍到此结束,谢谢您的阅读,有关12.21 php-fpm 的 pool 12.22 php-fpm 慢执行日志 12.23 open_basedir 12.24 php-fpm 进程管理、12.21 php-fpm的pool 12.22 php-fpm慢执行日志 12.23 open_basedir 12.24 php-fpm进程管理、12.21 php-fpm的pool12.22 php-fpm慢执行日志12.23 open_basedir12.24 php-fpm进程管理、5、PHP-将浮点数转为整数 php 浮点数比较 php 浮点数精度 php 浮点数格式等更多相关知识的信息可以在本站进行查询。

本文标签: