分类 PHP 下的文章

【译】PHP 7 中的可抛出(Throwable)异常及错误

以往,在 PHP 中处理致命错误几乎是不可能的。致命错误不会调用由 set_error_handler() 设置的错误处理程序,而只会停止脚本的执行。

在 PHP 7 中,当发生致命错误和可恢复错误(E_ERRORE_RECOVERABLE_ERROR)时,将抛出异常,而不是停止脚本执行。不过,致命错误在某些情况下仍然存在(比如内存不足),并会像以前一样立即停止脚本执行。未捕获的异常在 PHP 7 中仍是致命错误。即,如果一个由错误(该错误在 PHP 5.x 中是致命错误)抛出的异常未被捕获,它在 PHP 7 中仍将是一个致命错误。

请注意,其他类型的错误(如警告和通知)在 PHP 7 中保持不变。只有致命错误和可恢复错误才会抛出异常。

从致命错误和可恢复错误抛出的异常并不继承自 Exception 类。这是为了防止现有的 PHP 5.x 代码捕获以前会导致脚本停止执行的错误所引发的异常。从致命错误和可恢复错误抛出的异常是一个新的独立的异常类 Error 的实例。与所有其他异常一样,Error 可被捕获和处理,并能执行 finally 块中的代码。

- 阅读剩余部分 -

PHP 全文搜索引擎 TNTSearch

TNTSearch 是一个以 PHP 写就的功能完备的全文搜索引擎。

安装

最简单的安装方式是通过 composer 来安装 TNTSearch:

composer require teamtnt/tntsearch

系统要求

在继续之前,请确保您的服务器满足以下要求:

  • PHP >= 5.5
  • PDO PHP Extension
  • SQLite PHP Extension
  • mbstring PHP Extension

- 阅读剩余部分 -

PHP 数组函数 array_column

PHP 中的数组可以说是其最闪亮的语言特性之一,围绕数组操作,PHP 提供了数十个相关函数,今天本文介绍的 array_column 函数是这些函数中的小弟弟,首次出现于 PHP 5.5 中,它的作用是返回数组中指定列的所有值,如果不理解字面的解释,那我们看下面一段代码,$records 变量表示的是一个与数据库记录集对应的数组,数组中的每一项代表一条记录,每条记录包含三个字段(列):idfirst_namelast_name,如果我们想获得所有 first_name 字段(列)的值,在 PHP 5.5 之前,我们要用 foreach 语句或 array_walkarray_map 等函数来自编码实现,但自 PHP 5.5 起,我们只需简单调用 array_column 函数即可:

<?php
// 数组表示数据库返回的记录集
$records = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Jones',
    ),
    array(
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe',
    )
);
 
$first_names = array_column($records, 'first_name');

print_r($first_names);
?>

array_column 函数声明如下:

array array_column ( array $array , mixed $column_key [, mixed $index_key = null ] )

第一个参数是要操作的数组,第二个参数是要返回的字段(列)的键名,可选的第三个参数指定其值用作索引键的字段(列)名。

比如,在上面的例子中,输出结果如下:

Array
(
    [0] => John
    [1] => Sally
    [2] => Jane
    [3] => Peter
)

如果想指定 id 字段(列)的值作为返回数组的索引键,那么指定第三个参数为 id 即可:

<?php
// 使用上例中的记录数组
$first_names = array_column($records, 'first_name', 'id');
print_r($first_names);
?> 

输出结果如下:

Array
(
    [2135] => John
    [3245] => Sally
    [5342] => Jane
    [5623] => Peter
)

PHP 简单异步 HTTP 请求实现

某些情况下,我们只需要发出 HTTP 请求,并不需对其响应进行处理,以实现某种通知机制,那么使用异步方式发起该 HTTP 请求无疑更合适。在 PHP 中,我们可通过 fsockopen 函数来实现此需求,下面是代码:

function async_http_get($url, $host = '') {
    $host = empty($host) ? parse_url($url, PHP_URL_HOST) : $host;
    $host = empty($host) ? $_SERVER['HTTP_HOST'] : $host;

    $fp = fsockopen($host, 80, $errno, $errstr, 30);
    if (!$fp) {
        return "$errno: $errstr";
    }

    $out  = 'GET '.$url.' HTTP/1.1' . "\r\n";
    $out .= 'Host: '.$host."\r\n";
    $out .= 'Connection: close'."\r\n\r\n";

    fwrite($fp, $out);
    fclose($fp);

    return true;
}

PHP 中根据地理位置经纬度坐标计算两点距离

在涉及地理位置的应用场景中,往往需要计算两点的距离,比如根据用户所处位置,计算各门店与其距离。下面的 PHP 函数根据两点的经纬度坐标计算两点距离。

function calc_distance($lon1, $lat1, $lon2, $lat2)
{
    // 角度转换为弧度
    $ew1 = $lon1 * 0.01745329252;
    $ns1 = $lat1 * 0.01745329252;
    $ew2 = $lon2 * 0.01745329252;
    $ns2 = $lat2 * 0.01745329252;
    // 求大圆劣弧与球心所夹的角(弧度)
    $distance = sin($ns1) * sin($ns2) +
        cos($ns1) * cos($ns2) * cos($ew1 - $ew2);
    // 调整到[-1..1]范围内,避免溢出
    if ($distance > 1.0) {
         $distance = 1.0;
    } else if ($distance < -1.0) {
        $distance = -1.0;
    }
    // 求大圆劣弧长度
    $distance = 6370693.5 * acos($distance);
    return $distance;
}