1

我在根目录中有一个 PHP 应用程序,其中有 2 个名为“ database.php ”和“ Thread.php ”的文件(已从此处下载 Thread.php )。database.php 在连接到远程 MondoDb 数据库后执行一些琐碎的任务。这是 database.php 的代码:

<?php
include('Thread.php');

$dbUser = 'MyUserName';
$dbPass = 'MyPassword';
$dbHost = 'dsxxxxxx.mongolab.com';
$dbPort = 'xxxxx';
$dbName = 'MyDatabaseName';
$collectionName = 'TestCollection';

function connectToDatabase($dbUser, $dbPass, $dbHost, $dbPort, $dbName) {
    try {
        reconnect:
        echo "connecting to mongodb://{$dbUser}:{$dbPass}@{$dbHost}:{$dbPort}/{$dbName} ...<br/>";
        $database = new MongoClient("mongodb://{$dbUser}:{$dbPass}@{$dbHost}:{$dbPort}/{$dbName}");
        echo "connected ...<br/>";
    }
    catch (MongoConnectionException $e) {
        goto reconnect;
    }
    return $database->$dbName;
}

$database = connectToDatabase($dbUser, $dbPass, $dbHost, $dbPort, $dbName);

$collection = $database->$collectionName;

function modifyRecent($id, $error, $time) {
     global $database;
     echo "In function modifyRecent ...<br/>";
     //do something
     return;
}

function modifyAll($id, $error, $time) {
     global $database;
     echo "In function modifyAll ...<br/>";
     //do some other things
     return;
}

function updateDatabase($id, $error, $time) {
    echo "In function updateDatabase ...<br/>";
    if( ! Thread::available() ) {
        echo "Thread is not supported ...<br/>";
        return false;
    }

    $thread1 = new Thread('modifyAll');
    $thread2 = new Thread('modifyRecent');

    $thread1->start($id, $error, $time);
    $thread2->start($id, $error, $time);

    while($thread1->isAlive() || $thread2->isAlive()) {}

    return true;
}

updateDatabase((float)"1", (float)"12.6", (float)"23.7");

?>

现在当我从 shell () 运行这个脚本时php database.php......它显示了一个输出:

user@local_machine:~/AppDir$ php database.php 
connecting to mongodb://MyUserName:MyPassword@dsxxxxxx.mongolab.com:xxxxx/MyDatabaseName ...<br/>connected ...<br/>In function updateDatabase ...<br/>In function modifyAll ...<br/>In function modifyRecent ...<br/>
user@local_machine:~/AppDir$

这意味着一切顺利。

但是从浏览器( http://app.localhost/database.php )运行相同的脚本后,输出为:

connecting to mongodb://MyUserName:MyPassword@dsxxxxxx.mongolab.com:xxxxx/MyDatabaseName ...
connecting to mongodb://MyUserName:MyPassword@dsxxxxxx.mongolab.com:xxxxx/MyDatabaseName ...
connecting to mongodb://MyUserName:MyPassword@dsxxxxxx.mongolab.com:xxxxx/MyDatabaseName ...
connecting to mongodb://MyUserName:MyPassword@dsxxxxxx.mongolab.com:xxxxx/MyDatabaseName ...
connected ...
In function updateDatabase ...
Thread is not supported ...

PS:我已经配置了一个虚拟主机(http://app.localhost/),它指向我的应用程序的根目录(~/AppDir),以便在本地对其进行测试。

谁能指出我哪里错了?

4

1 回答 1

1

pcntl_fork()当 PHP 用作 Apache 模块时,无法使用该功能。您只能pcntl_fork()在 CGI 模式或命令行中使用。

Thread.php 使用pcntl_*()函数。

Thread::available()返回 false的原因就是因为这个。功能是:

public static function available() {
    $required_functions = array(
        'pcntl_fork',
    );

    foreach( $required_functions as $function ) {
        if ( !function_exists( $function ) ) {
            return false;
        }
    }

    return true;
}

由于您无权修改服务器。您可以通过执行以下操作将 PHP 文件作为 CGI 运行,前提是您的主机支持 CGI 和 .htaccess

创建一个 .htaccess 文件并将其放在 database.php 所在的文件夹中,并将以下内容放入其中:

Action php-script /FULL_PATH_TO_YOU_PHP_BINARY
AddHandler php-script php
于 2012-12-30T06:33:29.387 回答