如何将 JSON 或类对象传递给命令行 PHP 脚本


how to pass json or class object to command line php script

我有

$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() 函数,但有一些注意事项:

  1. 当然,你必须逃避它,例如用escapeshellarg
  2. 如果对象包含任何资源(例如fopen句柄,直接或间接(,则不会序列化它们,因此您将丢失它们
  3. 您的脚本必须知道您Google_Client类定义,以及它包含引用的任何类的定义。否则,它将被反序列化为__PHP_Incomplete_Class并且实际上无法使用。

检查手册页序列化

serialize(( 处理所有类型,除了 资源类型。您甚至可以序列化包含引用的 (( 数组 对自己。您所在的数组/对象内部的循环引用 还将存储序列化。任何其他引用都将丢失。 序列化对象时,PHP 将尝试调用成员函数 序列化之前的 __sleep((。这是为了允许对象在序列化之前执行任何最后一分钟的清理等。同样 当使用 unserialize(( 恢复对象时,__wakeup(( 成员 函数被调用。

和用于反序列化的那个

注意:unserialize_callback_func指令可以设置一个 将调用的回调函数,如果一个未定义的类应该 在反序列化期间实例化。(防止得到 不完整的对象"__PHP_Incomplete_Class"。使用你的 php.ini, ini_set(( 或 .htaccess 来定义 'unserialize_callback_func'。 每次应实例化未定义的类时,都会调用它。 要禁用此功能,只需清空此设置。