好玩的PHP(白眼)

大家在享受愉快的PHP生活吗?

\太开心啦!/\我超喜欢PHP/\我爱PHP/

我听到很多声音。
姐姐,我非常开心!
但是,虽然你喜欢PHP,但实际上它可能会有一些意想不到的行为哦。
或者为什么这样简单的处理却吃掉这么多内存呢?
你有过类似的经历吗?

也许在阅读这篇文章后,您曾经喜爱的PHP会变得讨厌,您可能想要和它分道扬镳。
或者相反,您也可能会变得更加喜欢它。
这取决于您自己。

开始时我会用这样的字眼开场,但实际上并没有什么内容。简单来说,这只是一个引人点击的手法。
由于标题本身已经包含了全部的信息,所以您不需要阅读接下来的内容。
好,那我们就开始吧。

在撰写本文时所使用的PHP版本如下:
PHP 7.1.3(cli)(构建日期:2017年3月14日17:39:59)(NTS版)
版权所有(c)1997-2017 PHP团队
Zend Engine v3.1.0,版权所有(c)1998-2017 Zend Tech

首先

在其他语言中普遍适用的规则,在PHP中可能变得不适用。反过来说,如果PHP是第一次接触的语言,这些问题可能不会成为困扰。但实际上,有一些情况是其他语言学习者接触PHP时会遇到较大的困难和挫折。我要先大声说出来的是,

PHP 是一种脚本语言。

范围的事情

PHP的作用域在某种程度上是装饰品。对于高手来说,他们无法理解它。

<?php
function test()
{
    {
        $value = "hello world\n";
        echo $value;
    }
    echo $value;
}
test();

执行时

你好世界
你好世界

這是

计算机算法相关

数字就是数字。它不是字符串类型或数值类型,只是数字。

<?php

function test()
{
    echo "3" + 9 . "\n";
    echo "3" + "9" . "\n";
    echo "3" . 9 . "\n";
    echo 3 . 9 . "\n";
}
test();

一旦执行

12
十二
39
三十九

在中国,有以下的一个选项:是的。

空 的事情

个人认为不应该经常使用null。与其使用null来判断对象是否为空,不如通过使用unset来删除不需要的对象,并使用如isset等函数来判断对象是否有效。

<?php

function test_isset()
{
    $value = "aaaa";
    echo (isset($value)?1:0) ."\n";
    $value = null;
    echo (isset($value)?1:0) ."\n";
    $value = "aaaa";
    unset($value);
    echo (isset($value)?1:0) ."\n";
}

function test_isnull()
{
    $value = "aaaa";
    echo (!is_null($value)?1:0) ."\n";
    $value = null;
    echo (!is_null($value)?1:0) ."\n";
    $value = "aaaa";
    unset($value);
    echo (!is_null($value)?1:0) ."\n";
}


function test_isset2()
{
    echo (isset($value)?1:0) ."\n";
    $value = null;
    echo (isset($value)?1:0) ."\n";
}

function test_isnull2()
{
    echo (!is_null($value)?1:0) ."\n";
    $value = null;
    echo (!is_null($value)?1:0) ."\n";
}

执行结果如下

test_isset ———————-
1
0
0
检测_isset ———————-
1
0
0
PHP 注意:变量 value 在 test.php 第22行未定义
0
检测_isnull ———————-
1
0
检测_isset2 ———————-
0
0
检测_isnull2———————-
PHP 注意:变量 value 在 test.php 第35行未定义
0
0

参考是邪恶的

<?php
function test()
{
    $values = array(1,2,3,4,5);
    foreach ( $values as &$value )
    {
        echo $value.",";
    }
    echo "\n";
    $value = 999;
    foreach ( $values as &$value )
    {
        echo $value.",";
    }
    echo "\n";
}
test();

一旦执行

一、二、三、四、五
一、二、三、四、九九九

请问您是否明白数可否?

注重写作时的「写时复制」方式

由于PHP的copy on write特性,通常处理时按引用方式处理(非复制)。一旦发生更改,将进行复制操作。换句话说,原本提到的引用在PHP中都是可以被排除的。与其他语言不同,在PHP中,更注重copy on write的设计,而不是通过引用传递值,可以编写出执行速度和内存使用量有优势的代码。

虽然有点麻烦,但可以将通常的值数组封装为类,并在传递到目标位置后修改成员变量。
通过这种写法,可以实现类似引用的行为。
个人认为,过于轻易地使用引用来避免问题是不好的做法。

首先,让我们通过一个示例来解释一下什么是“意识到copy on write”。

<?php

function test1()
{
    $sc = new stdClass();

    $sc->ary = array_fill(0, 999999, "aaaa");

    echo number_format(memory_get_usage()) . "byte \n";
}

function test2()
{
    $array_a = array_fill(0, 999999, "aaaa");

    $array_b = $array_a;

    $array_b[0] = 1;

    echo "array_a[0]:{$array_a[0]} array_b[0]:{$array_b[0]}\n";

    echo number_format(memory_get_usage()) . "byte \n";
}

function test3()
{
    $sc = new stdClass();

    $sc->ary = array_fill(0, 999999, "aaaa");

    $sc_ref = $sc;

    $sc_ref->ary[0] = 1;

    echo "sc->ary[0]:{$sc->ary[0]} sc_ref->ary[0]:{$sc_ref->ary[0]}\n";

    echo number_format(memory_get_usage()) . "byte \n";
}


echo "---\n";
test1();
echo "---\n";
test2();
echo "---\n";
test3();

执行结果如下所示

33,912,272字节
array_a[0]: aaaa array_b[0]: 1
67,470,464字节
sc->ary[0]: 1 sc_ref->ary[0]: 1
33,912,272字节

如果你在無意義的複製上有所涉入,建議重新考慮一下。

在运行Apache等服务器时使用PHP的注意事项

当在Apache等服务器上运行PHP时,PHP所分配的内存将加载到Apache本身上。
即使该内存在PHP脚本被释放后仍然存在,且直到Apache子进程终止,该内存也将保持被分配的状态。

这个情况不好细说,但最坏的情况是服务器内存不足导致崩溃。

PHP是一种脚本语言

你知道吗?PHP是一种脚本语言,是这样的。你明白吗?