是否可以在curl请求完成后注册一些回调函数以释放资源?

问题描述 投票:0回答:2

对于某些库,我想添加一个curl调试函数,在某些情况下可以调用该函数。但是我偶然发现了一些释放资源的问题。

这是我的库函数:

/**
 * @param $curlhandle: The curlhandle resource which was created by curl_init();
 * @param null $log_location: Log location folder. If empty the wp-content directory will be used.
 * @param string $log_file_name: The name of the logfile to be written.
 */
function cis_curl_add_debug($curlhandle, $log_location = null, $log_file_name = "cis-curl-errorlog.txt") {

    if(!is_resource($curlhandle)) {
        trigger_error("Incorrect call to cis_curl_add_debug function: Expected curl handle.",E_USER_WARNING);
        return;
    }

    if (!$log_location) {
        $log_folder = realpath(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'logs');
        if(!is_dir($log_folder)) {
            mkdir($log_folder,776);
        }
    }

    $fp = fopen($log_folder . DIRECTORY_SEPARATOR . $log_file_name, 'w');
    curl_setopt($curlhandle, CURLOPT_VERBOSE, 1);
    curl_setopt($curlhandle, CURLOPT_STDERR, $fp);

    return $curlhandle;
}

这是一个用法示例:

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json');

    $ch = cis_curl_add_debug($ch);
    $result = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

基本上,这应该与一个小小的事实一起起作用:$ fp文件指针永远不会用fclose()关闭。这意味着该日志文件已被锁定以进行写入,并且如果我多次调用他的函数,则该日志文件将无法写入(或者如果其他任何应用程序想要这样做)。

所以我的想法是注册一些功能-pseudocode

curl_setopt($curlhandle, CURLOPT_DESTRUCTION_CALLBACK, function () use ($fp) {
    fclose($fp);
}

但是我还没有发现这种可能性。也许有解决此问题的更明显方法?

php curl logging resources file-handling
2个回答
2
投票

由于句柄$ch通过引用作用,因此您无需返回该句柄。您可以选择让函数执行更多操作:

function cis_curl_add_debug($curlhandle, $log_location = null, $log_file_name = "cis-curl-errorlog.txt") {

    if(!is_resource($curlhandle)) {
        trigger_error("Incorrect call to cis_curl_add_debug function: Expected curl handle.",E_USER_WARNING);
        return;
    }

    if (!$log_location) {
        $log_folder = realpath(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'logs');
        if(!is_dir($log_folder)) {
            mkdir($log_folder,776);
        }
    }

    $fp = fopen($log_folder . DIRECTORY_SEPARATOR . $log_file_name, 'w');
    curl_setopt($curlhandle, CURLOPT_VERBOSE, 1);
    curl_setopt($curlhandle, CURLOPT_STDERR, $fp);

    $result = curl_exec($curlhandle);

    fclose($fp);

    return $result;
}

用法:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json');

$result = cis_curl_add_debug($ch);
$error = curl_error($ch);
curl_close($ch);

注意:

您可能还希望重命名函数以表示CURL的执行。

[这篇文章解释了我以$ch的方式使用Are php resources passed by reference?的基础:


1
投票

这是我最终解决它的方法:

© www.soinside.com 2019 - 2024. All rights reserved.