2016-04-07 14 views
0

Jobbyを私のcronjobsマネージャーとしてPDOに使用しようとしています。私はSuperClosure(Jobbyでも使用されています)を使用してクロージャをシリアル化し、データベースに挿入しました。それから私は私のデータベースからすべてのレコードを取得し、私はJobbyへのジョブとして、それを追加する前に閉鎖をunseralizeが、私が得るすべては次のとおりです。Jobby/SuperClosureが機能していません: "...:eval() 'dコード"を含むファイルが存在しませんでした

ルート@テスト:/ホーム/.../ public_htmlの/パブリックます。#/ usr/local/bin/php ./cron.php PHPの注意:クロージャのシリアライズに失敗しました:クロージャを含むファイル "/home/.../public_html/vendor/jeremeamia/SuperClosure/src/SerializableClosure.php(210): eval() 'd code'は存在しませんでした。閉鎖のシリアル化に失敗しました::閉鎖を含むファイルを、「/home/.../ /home/.../public_html/vendor/jeremeamia/SuperClosure/src/SerializableClosure.phpライン上の117
お知らせでpublic_html/vendor/jeremeamia/SuperClosure/src/SerializableClosure.php(210):eval() 'd code "が存在しませんでした。 にライン上の/home/.../public_html/vendor/jeremeamia/SuperClosure/src/SerializableClosure.phpここ

は私のコードです:

$config = array(
    'output' => ROOT_PATH . 'closure.log', 
    'debug' => 1, 
); 
$jobby = new Jobby\Jobby($config); 
$serializer = new SuperClosure\Serializer(); 

$jobs = $model->getCronJobs(); 
foreach ($jobs as $job) 
{ 
    $job = array_filter($job); 

    try { 
     $job['closure'] = $serializer->unserialize($job['closure']); 
     unset($job['command']); 
    } catch (SuperClosure\Exception\ClosureUnserializationException $e) { 
    } 

    $jobName = $job[ 'name' ]; 
    unset($job[ 'name' ]); 
    unset($job[ 'id' ]); 

    $jobby->add($jobName, $job); 
} 

$jobby->run(); 

そして、何I $model->getCronJobs();から入手:

array(1) { 
    [0]=> 
    array(23) { 
     ["id"]=> 
     string(2) "11" 
     ["name"]=> 
     string(9) "testzcron" 
     ["command"]=> 
     string(1) " " 
     ["closure"]=> 
     string(243) "C:32:"SuperClosure\SerializableClosure":197:{a:5:{s:4:"code";s:                                        102:"function() { 
     echo 'I\'m a function (' . date('Y-m-d H:i:s') . ')!' . PHP_EOL; 
     return true; 
     };";s:7:"context";a:0:{}s:7:"binding";N;s:5:"scope";N;s:8:"isStatic";b:0;}}" 
     ["schedule"]=> 
     string(9) "* * * * *" 
     ["mailer"]=> 
     string(4) "smtp" 
     ["maxRuntime"]=> 
     NULL 
     ["recipients"]=> 
     NULL 
     ["smtpHost"]=> 
     NULL 
     ["smtpPort"]=> 
     NULL 
     ["smtpUsername"]=> 
     NULL 
     ["smtpPassword"]=> 
     NULL 
     ["smtpSender"]=> 
     string(15) "[email protected]" 
     ["smtpSenderName"]=> 
     string(5) "Jobby" 
     ["smtpSecurity"]=> 
     NULL 
     ["runAs"]=> 
     NULL 
     ["environment"]=> 
     NULL 
     ["runOnHost"]=> 
     NULL 
     ["output"]=> 
     NULL 
     ["dateFormat"]=> 
     string(11) "Y-m-d H:i:s" 
     ["enabled"]=> 
     string(1) "1" 
     ["haltDir"]=> 
     NULL 
     ["debug"]=> 
     string(1) "0" 
    } 
} 

logファイルから:

PHP Fatal error: Uncaught exception 'SuperClosure\Exception\ClosureUnserializationException' with message 'The closure did not unserialize to a SuperClosure.' in /home/.../public_html/vendor/jeremeamia/SuperClosure/src/Serializer.php:103 
Stack trace: 
#0 /home/.../public_html/vendor/hellogerard/jobby/src/BackgroundJob.php(233): SuperClosure\Serializer->unserialize('N;') 
#1 /home/.../public_html/vendor/hellogerard/jobby/src/BackgroundJob.php(88): Jobby\BackgroundJob->runFunction() 
#2 /home/.../public_html/vendor/hellogerard/jobby/bin/run-job(20): Jobby\BackgroundJob->run() 
#3 {main} 
thrown in /home/.../public_html/vendor/jeremeamia/SuperClosure/src/Serializer.php on line 103 

編集:

$serializer->unserialize($job['closure']);は次のとおりです。

object(Closure)#9 (0) { 
} 

と私はそれを呼び出すとき、それは完全に正常に動作します:

[email protected]:/home/.../public_html/public# /usr/local/bin/php cron.php 
I'm a function (2016-04-13 11:46:52)! 
bool(true) 
+0

'$ serializer-> unserialize($ job ['closure']);'の結果をログに記録できますか? – magnetik

+0

@magnetik編集に追加されました:) – simivar

答えて

1

何が起こっているの閉鎖をunserializingことによって自分自身が(使用していることですSuperClosure)を使用すると、クロージャの別のコンテキストが作成されます。このコンテキストを使用して、再度シリアル化することはできません。長いバージョン:

SuperClosureはReflectionを使用します。あなたが渡したクロージャを受け入れ、実際にこのクロージャが作成されたphpファイルを探し出します。これは、元のソースを格納することによって、ランタイムClosureを直列化可能なコードに '変換'する唯一の方法です。あなたはしかし、これはあなたが(そのソースとしてeval機能付き)を使用することができます(ランタイムで)新しいクロージャーを作成

  • を実行時にシリアライズ変換することeval()を使用してindirectly
  • ある$serializer->unserialize()を呼び出すことによって

    • SuperClosureは、この閉鎖のためのソースを必要とする(ランタイムから)このクロージャをシリアライズするuses SuperClosureをjobby、およびusesReflection
    • 代わりに、コードの実際のソースを見つけることのあなたの閉鎖のためのコードを見つけるために、それは本当にこのコード
    溶液は、溶媒として

    が含まれていないeval()を見つけ、私は思いますこの行を削除するのが最善の方法です:

    $job['closure'] = $serializer->unserialize($job['closure']); 
    

    あなたのスーパークローズを直接受け入れるように頼んでください。あなたはこのようにJobbyを更新する必要があります

     protected function getExecutableCommand($job, array $config) 
        { 
    -  if (isset($config['closure'])) { 
    +  if (isset($config['closure']) && gettype($config['closure']) != 'string') { 
          $config['closure'] = $this->getSerializer()->serialize($config['closure']); 
         } 
    

    しかし、私が使用したことがないSuperClosureまたはJobbyと私は本当にこれをテストすることはできません。これが動作するかどうかお知らせください。