文章851
标签121
分类10

PHP `array_walk`、`array_map` 和 `foreach` 性能测试比较

在 PHP 中,array_walkarray_mapforeach 是常用的数组处理方法。它们在性能和用法上有一些不同。下面我们将对这三种方法进行性能测试比较。

1. 方法概述

1.1 array_walk

array_walk 用于对数组中的每个元素应用用户自定义的回调函数。它对原数组进行操作,且不返回新数组。

array_walk($array, 'callback_function');

1.2 array_map

array_map 用于对数组中的每个元素应用用户自定义的回调函数,并返回一个新数组。

$newArray = array_map('callback_function', $array);

1.3 foreach

foreach 是一种语言结构,用于遍历数组的每个元素。您可以在循环中直接修改数组或执行操作。

foreach ($array as $value) {
    // 操作
}

2. 性能测试

我们将使用一个简单的性能测试来比较这三种方法。测试的内容是将一个大数组中的每个元素进行简单的加倍操作。

2.1 测试代码

<?php

function double($value) {
    return $value * 2;
}

$array = range(1, 100000); // 创建一个包含100000个整数的数组

// array_walk
$start = microtime(true);
array_walk($array, function(&$value) {
    $value = double($value);
});
$time_walk = microtime(true) - $start;

// array_map
$start = microtime(true);
$newArrayMap = array_map('double', $array);
$time_map = microtime(true) - $start;

// foreach
$start = microtime(true);
foreach ($array as &$value) {
    $value = double($value);
}
$time_foreach = microtime(true) - $start;

// 显示结果
echo "array_walk took: {$time_walk} seconds\n";
echo "array_map took: {$time_map} seconds\n";
echo "foreach took: {$time_foreach} seconds\n";
?>

2.2 运行测试

将上述代码保存为 performance_test.php 并在命令行中运行:

php performance_test.php

3. 性能结果分析

根据测试结果,您将看到每种方法所用的时间。以下是可能的结果分析:

  • foreach 通常是最快的,因为它是语言结构,开销最小。
  • array_map 通常速度较快,但会创建一个新数组,可能会消耗更多内存。
  • array_walk 可能会稍慢,因为它涉及到回调函数的调用,并且没有返回新数组。

4. 结论

  • 如果您需要返回新数组,使用 array_map
  • 如果您只需要对原数组进行操作,foreach 是最佳选择。
  • array_walk 用于更复杂的操作,但通常性能不如 foreach

在 Linux 中将 PHP-FPM 配置成 Service

在 Linux 系统中,您可以将 PHP-FPM 配置为服务,以便更方便地管理其启动、停止和重启。以下是在常见的 Linux 发行版(如 CentOS 和 Ubuntu)中配置 PHP-FPM 为服务的步骤。

1. 安装 PHP-FPM

首先,确保您已安装 PHP-FPM。根据您的 Linux 发行版,您可以使用以下命令进行安装。

CentOS

sudo yum install php-fpm

Ubuntu

sudo apt update
sudo apt install php-fpm

2. 配置 PHP-FPM

在安装完成后,您需要配置 PHP-FPM。编辑配置文件,通常位于 /etc/php-fpm.d/www.conf/etc/php/7.x/fpm/pool.d/www.conf(具体路径可能因 PHP 版本和发行版而异)。

sudo nano /etc/php-fpm.d/www.conf  # CentOS

sudo nano /etc/php/7.x/fpm/pool.d/www.conf  # Ubuntu

确保以下配置项设置正确:

listen = 127.0.0.1:9000  # 配置 PHP-FPM 监听的地址和端口

3. 创建 Systemd 服务文件

CentOS / Ubuntu

您可以创建一个 Systemd 服务文件来管理 PHP-FPM。通常,该文件位于 /etc/systemd/system/

sudo nano /etc/systemd/system/php-fpm.service

在文件中添加以下内容:

[Unit]
Description=The PHP 7.x FastCGI Process Manager
After=network.target

[Service]
Type=simple
PIDFile=/run/php/php7.x-fpm.pid  # 根据您的 PHP 版本修改
ExecStart=/usr/sbin/php-fpm7.x --nodaemonize  # 根据您的 PHP 版本修改
ExecReload=/bin/kill -USR2 $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

注意事项

  • 确保 ExecStart 中的 PHP-FPM 路径和版本号正确。
  • 对于 PHP 7.4,通常是 php-fpm7.4;对于 PHP 8.0,则是 php-fpm8.0

4. 重新加载 Systemd

创建或修改服务文件后,您需要重新加载 Systemd,以便它识别新服务。

sudo systemctl daemon-reload

5. 启动 PHP-FPM 服务

使用以下命令启动 PHP-FPM 服务:

sudo systemctl start php-fpm

6. 设置开机自启

如果您希望 PHP-FPM 在系统启动时自动启动,可以使用以下命令:

sudo systemctl enable php-fpm

7. 管理 PHP-FPM 服务

您可以使用以下命令管理 PHP-FPM 服务:

  • 检查状态

    sudo systemctl status php-fpm
  • 停止服务

    sudo systemctl stop php-fpm
  • 重启服务

    sudo systemctl restart php-fpm
  • 重新加载配置

    sudo systemctl reload php-fpm

8. 配置防火墙(可选)

如果您使用的是防火墙(如 firewalldufw),确保允许 PHP-FPM 的监听端口(默认是 9000)。

CentOS(firewalld)

sudo firewall-cmd --add-port=9000/tcp --permanent
sudo firewall-cmd --reload

Ubuntu (ufw)

sudo ufw allow 9000/tcp

PHP Kafka 初体验

Apache Kafka 是一个分布式流处理平台,广泛用于构建实时数据管道和流应用。以下是使用 PHP 操作 Kafka 的基本步骤和示例,帮助您快速上手。

1. 环境准备

1.1 安装 Kafka

首先,您需要在本地或服务器上安装 Kafka。可以从 Kafka 官方网站 下载并解压 Kafka。

1.2 启动 Kafka 和 Zookeeper

Kafka 依赖 Zookeeper,因此需要先启动 Zookeeper:

bin/zookeeper-server-start.sh config/zookeeper.properties

然后启动 Kafka 服务器:

bin/kafka-server-start.sh config/server.properties

1.3 安装 PHP 扩展

为了在 PHP 中使用 Kafka,您可以使用 php-rdkafka 扩展。您可以通过 PECL 安装:

sudo pecl install rdkafka

确保在 php.ini 文件中添加以下行:

extension=rdkafka.so

2. 创建 Kafka 主题

在使用 Kafka 之前,您需要创建一个主题。可以使用以下命令创建一个名为 test 的主题:

bin/kafka-topics.sh --create --topic test --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1

3. PHP 生产者示例

下面是一个简单的 PHP 生产者示例,用于发送消息到 Kafka 主题:

<?php
$conf = new RdKafka\Conf();
$conf->set('metadata.broker.list', 'localhost:9092'); // 设置 broker 地址

$producer = new RdKafka\Producer($conf);
$topic = $producer->newTopic("test");

for ($i = 0; $i < 10; $i++) {
    $message = "Message $i";
    $topic->produce(RD_KAFKA_PARTITION_UA, 0, $message);
    echo "Sent: $message\n";
}

$producer->flush(10000); // 确保消息发送
?>

4. PHP 消费者示例

下面是一个简单的 PHP 消费者示例,用于从 Kafka 主题中接收消息:

<?php
$conf = new RdKafka\Conf();
$conf->set('metadata.broker.list', 'localhost:9092'); // 设置 broker 地址

$consumer = new RdKafka\Consumer($conf);
$consumer->addBrokers("localhost:9092");

$topic = $consumer->newTopic("test");
$topic->consumeStart(0, RD_KAFKA_OFFSET_END); // 从最新位置开始消费

while (true) {
    $message = $topic->consume(0, 1000); // 等待消息

    if ($message->err) {
        if ($message->err == RD_KAFKA_RESP_ERR__TIMED_OUT) {
            continue;
        }
        echo "Consumer error: {$message->err}\n";
        break;
    }

    echo "Received: {$message->payload}\n";
}
?>

5. 运行示例

  1. 运行生产者:在一个终端中运行生产者脚本:

    php producer.php
  2. 运行消费者:在另一个终端中运行消费者脚本:

    php consumer.php

您应该能够看到生产者发送的消息被消费者接收。

PHP异常处理中的黑科技

PHP异常处理中的黑科技

  前面提到框架中是可以捕获所有的错误和异常的,之所以能实现应该是使用了黑科技,哈哈!其实也不是什么黑科技,主要是三个重要的函数:

1. set_error_handler()

看到这个名字估计就知道什么意思了,这个函数用于捕获错误,设置一个用户自定义的错误处理函数。

  当程序出现错误的时候自动调用此方法,不过需要注意一下两点:
第一,如果存在该方法,相应的error_reporting()就不能在使用了。所有的错误都会交给自定义的函数处理。
第二,此方法不能处理以下级别的错误:E_ERRORE_PARSEE_CORE_ERRORE_CORE_WARNINGE_COMPILE_ERRORE_COMPILE_WARNINGset_error_handler() 函数所在文件中产生的E_STRICT,该函数只能捕获系统产生的一些WarningNotice级别的错误。

  并且他有多种调用的方法:

2. register_shutdown_function()

捕获PHP的错误:Fatal ErrorParse Error等,这个方法是PHP脚本执行结束前最后一个调用的函数,比如脚本错误、die()、exit、异常、正常结束都会调用,多么牛逼的一个函数啊!
通过这个函数就可以在脚本结束前判断这次执行是否有错误产生,这时就要借助于一个函数:error_get_last()
这个函数可以拿到本次执行产生的所有错误。error_get_last();

返回的信息:

  •   [type] - 错误类型
    -  [message] - 错误消息
    -  [file] - 发生错误所在的文件
    -  [line] - 发生错误所在的行

3:set_exception_handler()

设置默认的异常处理程序,用在没有用try/catch块来捕获的异常,也就是说不管你抛出的异常有没有人捕获,如果没有人捕获就会进入到该方法中,并且在回调函数调用后异常会中止。

php.ini 中display_errors = Off 失效的解决

php.inidisplay_errors = Off 失效的解决
  

问题: PHP设置文件php.ini中明明已经设置display_errors = Off,但是在运行过程中,网页上还是会出现错误信息。

  
解决: log_errors= On,据官方的说法,当这个log_errors设置为On,那么必须指定error_log文件,如果没指定或者指定的文件没有权限写入,那么照样会输 出到正常的输出渠道,那么也就使得display_errors 这个指定的Off失效,错误信息还是打印了出来。
于是将 log_errors = Off,问题就解决了。

">