1

ルートディレクトリに「 database.php」と「Thread.php 」という名前の2つのファイルがある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");

?>

シェルからこのスクリプトを実行すると(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/ )を構成しました。

誰かが私が間違っているところを指摘できますか?

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

サーバーを変更するためのアクセス権がないため。ホストがCGIと.htaccessをサポートしている場合は、次のようにしてPHPファイルをCGIとして実行できます。

.htaccessファイルを作成し、database.phpがあるフォルダーに配置し、その中に次のファイルを配置します。

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