Serialization of closure failed: Serialization of 'Closure' is not allowed
wujekbogdan opened this issue · comments
I'm having a strange issue. I'm getting a:
Notice: Serialization of closure failed: Serialization of 'Closure' is not allowed in /path/to/php/file.php
error.
This happens only when I use the use
statement. So this code is causing the issue:
$app = new App();
$config = $app->config();
$logger = $app->getLogger();
$jobby->add('export-all', [
'schedule' => $config->get("cron:export-all"),
'closure' => function () use ($app, $logger, $config) {
// Do something
},
]);
But this is fine:
$jobby->add('export-all', [
'schedule' => $config->get("cron:export-all"),
'closure' => function () {
$app = new App();
$config = $app->config();
$logger = $app->getLogger();
// Do something
},
]);
But, this is not a rule! Not always when I use the use
statement I'm having this issue. But always when I'm getting this issue getting rid of the use
statement solves the problem.
I know that Jobby is using SuperClosure internally, so it probably has something to to with SuperClosure not Jobby itself.
Closing in favor of #93
Hi, I know this issue is already closed, but I face the same is issue from the jobby-pdo example https://github.com/jobbyphp/jobby/blob/master/resources/jobby-pdo.php
➜ cp vendor/hellogerard/jobby/resources/jobby-pdo.php .
➜ nano jobby-pdo.php # update autoload.php path
➜ php70 jobby-pdo.php
PHP Notice: Serialization of closure failed: The file containing the closure, "/home/arie/proj/Task/vendor/jeremeamia/SuperClosure/src/SerializableClosure.php(210) : eval()'d code" did not exist. in /home/arie/proj/Task/vendor/jeremeamia/SuperClosure/src/SerializableClosure.php on line 116
my environments: PHP 7.0.31 on Linux
@ariews Did you attempt the solution in #93 (comment)?
yes, I tried to add require_once __DIR__.'/vendor/autoload.php
to the closure, but no luck.
I Just copied the jobby example, and update the vendor/autoload.php path, and adding vendor/autoload.php on closure. here is the file:
<?php
//
// This script demonstrates how to use jobby with a PDO-backend, which is used to
// save the jobby-cronjob/jobbies configuration.
//
// Adapt this file to your needs, copy it to your project-root,
// and add this line to your crontab file:
//
// * * * * * cd /path/to/project && php jobby-pdo.php 1>> /dev/null 2>&1
//
# update path
require_once __DIR__ . '/vendor/autoload.php';
// The table, which shall contain the cronjob-configuration(s).
$dbhJobbiesTableName = 'jobbies';
/*
* For demo-purposes, an in-memory SQLite database is used.
*
* !!! REPLACE WITH YOUR OWN DATASOURCE!!!
*/
$dbh = new PDO('sqlite::memory:');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/*
* Setup a test-fixture, having two jobs, first one is a system-cmd (date), second one is a Closure
* (which is saved to pdo-database).
*/
$dbh->exec("
CREATE TABLE IF NOT EXISTS `$dbhJobbiesTableName`
(`name` VARCHAR(255) NOT NULL ,
`command` TEXT NOT NULL ,
`schedule` VARCHAR(255) NOT NULL ,
`mailer` VARCHAR(255) NULL DEFAULT 'sendmail' ,
`maxRuntime` INT UNSIGNED NULL ,
`smtpHost` VARCHAR(255) NULL ,
`smtpPort` SMALLINT UNSIGNED NULL ,
`smtpUsername` VARCHAR(255) NULL ,
`smtpPassword` VARCHAR(255) NULL ,
`smtpSender` VARCHAR(255) NULL DEFAULT 'jobby@localhost' ,
`smtpSenderName` VARCHAR(255) NULL DEFAULT 'Jobby' ,
`smtpSecurity` VARCHAR(20) NULL ,
`runAs` VARCHAR(255) NULL ,
`environment` TEXT NULL ,
`runOnHost` VARCHAR(255) NULL ,
`output` VARCHAR(255) NULL ,
`dateFormat` VARCHAR(100) NULL DEFAULT 'Y-m-d H:i:s' ,
`enabled` BOOLEAN NULL DEFAULT TRUE ,
`haltDir` VARCHAR(255) NULL , `debug` BOOLEAN NULL DEFAULT FALSE ,
PRIMARY KEY (`name`)
)
");
$insertCronJobConfiguration = $dbh->prepare("
INSERT INTO `$dbhJobbiesTableName`
(`name`,`command`,`schedule`,`output`)
VALUES
(:name,:command,:schedule,:output)
");
// First demo-job - print "date" to logs/command-pdo.log.
$insertCronJobConfiguration->execute(
['CommandExample', 'date', '* * * * *', 'logs/command-pdo.log']
);
// Second demo-job - a Closure which does some php::echo(). The Closure is saved to PDO-backend, too.
$secondJobFn = function() {
# add autoload
require_once __DIR__ . '/vendor/autoload.php';
echo "I'm a function (" . date('Y-m-d H:i:s') . ')!' . PHP_EOL;
return true;
};
$serializer = new SuperClosure\Serializer();
$secondJobFnSerialized = $serializer->serialize($secondJobFn);
$insertCronJobConfiguration->execute(
['ClosureExample', $secondJobFnSerialized, '* * * * *', 'logs/closure-pdo.log']
);
/*
* Examples are now set up, and saved to PDO-backend.
*
* Now, fetch all jobbies from PDO-backend and run them.
*/
$jobbiesStmt = $dbh->query("SELECT * FROM `$dbhJobbiesTableName`");
$jobbies = $jobbiesStmt->fetchAll(PDO::FETCH_ASSOC);
$jobby = new \Jobby\Jobby();
foreach ($jobbies as $job) {
// Filter out each value, which is not set (for example, "maxRuntime" is not defined in the job).
$job = array_filter($job);
try {
$job['closure'] = $serializer->unserialize($job['command']);
unset($job['command']);
} catch (SuperClosure\Exception\ClosureUnserializationException $e) {
}
$jobName = $job['name'];
unset($job['name']);
$jobby->add($jobName, $job);
}
$jobby->run();
if you are curious about the modules:
➜ php70 -m
[PHP Modules]
apcu
Core
ctype
curl
date
dom
fileinfo
filter
gd
hash
iconv
imagick
json
libxml
mbstring
mcrypt
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
pgsql
Phar
posix
readline
redis
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
xsl
zip
zlib
[Zend Modules]