相同的PHP脚本在浏览器中显示的输出与从命令行运行时不同

时间:2012-12-30 06:27:39

标签: php multithreading mongodb

我在根目录中有一个PHP应用程序,其中有2个文件名为“ database.php ”& “ Thread.php ”(Thread.php已从here下载)。在连接到远程MondoDb数据库之后,database.php执行一些简单的任务。这是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:我已经配置了一个指向我应用的根目录(〜/ AppDir )的虚拟主机( http://app.localhost/ ),以便在本地测试。

有人能指出我哪里弄错了吗?

1 个答案:

答案 0 :(得分:1)

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

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;
}

由于您无权修改服务器。如果您的主机支持CGI和.htaccess

,您可以通过执行以下操作将CG文件作为CGI 运行运行

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

Action php-script /FULL_PATH_TO_YOU_PHP_BINARY
AddHandler php-script php