我有
$client = new Google_Client();
它是 json 中的令牌。
现在我想通过 shell_exec(( 将此客户端对象以及 json 令牌传递给另一个脚本。
让我们假设命令为
php myscript.php var1 var2 $client $token
现在,由于命令行将所有参数作为字符串,因此我无法传递json和客户端对象。 对于 json,我找到了可以传递给命令提示符的serialize()
和unserialize()
函数,但是$client
对象如何将其传递给命令提示符呢?请帮忙。
序列化也会"字符串化"对象!您还可以对参数进行base64编码/解码,以防止出现特殊的字符问题:
$aArgs = array($client, $token);
$sArgs = base64_encode(serialize($aArgs));
exec('php myscript.php '.$sArgs);
我会使用 json_encode((:
存储 PHP 数组的首选方法(json_encode vs 序列化(
TLDR?json_encode(( 可能存在一些问题:
- 默认情况下,json_encode(( 将 UTF-8 字符转换为 Unicode 转义序列,而序列化((不。 注意:保留 UTF-8 字符原封不动,您可以使用 PHP JSON_UNESCAPED_UNICODE的选项5.4.
- JSON 将没有对象的原始类的内存(它们始终恢复为 stdClass 的实例(。
- 不能将 __sleep(( 和 __wakeup(( 与 JSON 结合使用
- 只有公共属性使用 JSON 序列化
- JSON 更具可移植性
但是,如果这些事情都不是您的用例的问题,它比 serialize(( 快 100-150%。(解码字符串时,您的 Google_Client(( 类将转换为标准类(。
// Script that kicks off the background task
$aArgs = array($client, $token);
$sArgs = base64_encode(json_encode($aArgs));
exec('php myscript.php '.$sArgs . ' > /dev/null 2>/dev/null &');
// myscript.php
$sArgs = json_decode(base64_decode($argv[1]));
// do something with $sArgs here...
有点棘手。
首先,如果要将完全相同的对象传递给另一个脚本,为什么不include
呢?或者创建一些函数来代替运行?
其次,为什么不在那个脚本中创建对象呢?这会为您省去很多麻烦。
如果绝对必须通过shell_exec将对象传递给另一个脚本,则可以使用 serialize()
函数,但有一些注意事项:
- 当然,你必须逃避它,例如用
escapeshellarg
- 如果对象包含任何资源(例如
fopen
句柄,直接或间接(,则不会序列化它们,因此您将丢失它们 - 您的脚本必须知道您Google_Client类定义,以及它包含引用的任何类的定义。否则,它将被反序列化为__PHP_Incomplete_Class并且实际上无法使用。
检查手册页序列化
serialize(( 处理所有类型,除了 资源类型。您甚至可以序列化包含引用的 (( 数组 对自己。您所在的数组/对象内部的循环引用 还将存储序列化。任何其他引用都将丢失。 序列化对象时,PHP 将尝试调用成员函数 序列化之前的 __sleep((。这是为了允许对象在序列化之前执行任何最后一分钟的清理等。同样 当使用 unserialize(( 恢复对象时,__wakeup(( 成员 函数被调用。
和用于反序列化的那个
注意:unserialize_callback_func指令可以设置一个 将调用的回调函数,如果一个未定义的类应该 在反序列化期间实例化。(防止得到 不完整的对象"__PHP_Incomplete_Class"。使用你的 php.ini, ini_set(( 或 .htaccess 来定义 'unserialize_callback_func'。 每次应实例化未定义的类时,都会调用它。 要禁用此功能,只需清空此设置。