bash 如何将 json 或 class 对象传递给命令行 php 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19024421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:04:06  来源:igfitidea点击:

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

phpbashoopshellcommand-line

提问by Vivek Muthal

I have

我有

$client = new Google_Client();

And it's token in json.

它是json中的令牌。

Now I want to pass this client object as well as json token to another script via shell_exec().
Let's assume command as

现在我想通过 shell_exec() 将此客户端对象以及 json 令牌传递给另一个脚本。
让我们假设命令为

php myscript.php var1 var2 $client $token

Now as command line takes all argument as string I am not able to pass the json and client object. For json I found serialize()and unserialize()functions that I can pass to command prompt but what about $clientobject how to pass it to command prompt? Please Help.

现在命令行将所有参数作为字符串,我无法传递 json 和客户端对象。对于我发现的 jsonserialize()unserialize()我可以传递给命令提示符的函数,但是$client对象如何将它传递给命令提示符呢?请帮忙。

采纳答案by siergiej

This is kind of tricky.

这有点棘手。

First and foremost, if you want to pass exactly the same object to another script, why dont you includeit? Or create some function to run instead?

首先,如果您想将完全相同的对象传递给另一个脚本,为什么不include呢?或者创建一些函数来运行?

Second, why don't you create your object in that script? It would save you a lot of trouble.

其次,为什么不在该脚本中创建对象?它会为你省去很多麻烦。

If you absolutely have to pass the object to another script via shell_exec, you may use the serialize()function, but there are a few caveats:

如果您绝对必须通过 shell_exec 将对象传递给另一个脚本,您可以使用该serialize()函数,但有一些注意事项:

  1. Of course you have to escape it, e.g. with escapeshellarg
  2. If your object contains any resources (such as fopenhandle, directly or indirectly), they will not be serialized and thus you will lose them
  3. Your script must be aware of yout Google_Client class definition, and definition of any class that it contains reference to. Otherwise it will be unserialized as __PHP_Incomplete_Class and effectively unusable.
  1. 当然你必须逃避它,例如 escapeshellarg
  2. 如果您的对象包含任何资源(例如fopen句柄,直接或间接),它们将不会被序列化,因此您将丢失它们
  3. 您的脚本必须知道您的 Google_Client 类定义,以及它包含引用的任何类的定义。否则它将被反序列化为 __PHP_Incomplete_Class 并且实际上无法使用。

check the manual page serialize

检查手册页序列化

serialize() handles all types, except the resource-type. You can even serialize() arrays that contain references to itself. Circular references inside the array/object you are serializing will also be stored. Any other reference will be lost. When serializing objects, PHP will attempt to call the member function __sleep() prior to serialization. This is to allow the object to do any last minute clean-up, etc. prior to being serialized. Likewise, when the object is restored using unserialize() the __wakeup() member function is called.

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

and the one for unserialize

和一个反序列化

Note: unserialize_callback_func directive It's possible to set a callback-function which will be called, if an undefined class should be instantiated during unserializing. (to prevent getting an incomplete object "__PHP_Incomplete_Class".) Use your php.ini, ini_set() or .htaccess to define 'unserialize_callback_func'. Everytime an undefined class should be instantiated, it'll be called. To disable this feature just empty this setting.

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

回答by Nassim

Serialize will also "stringify" objects! You can also base64 encode/decode your arguments to prevent special chars troubles :

序列化还将“串化”对象!您还可以对您的参数进行 base64 编码/解码以防止特殊字符问题:

$aArgs = array($client, $token);
$sArgs = base64_encode(serialize($aArgs));
exec('php myscript.php '.$sArgs);

回答by Silas Palmer

I'd use json_encode():

我会使用 json_encode():

Preferred method to store PHP arrays (json_encode vs serialize)

存储 PHP 数组的首选方法(json_encode 与序列化)

TLDR? There are some possible issues with json_encode():

TLDR?json_encode() 可能存在一些问题:

  • By default, json_encode() converts UTF-8 characters to Unicode escape sequences while serialize() does not. Note: To leave UTF-8 characters untouched, you can use the option JSON_UNESCAPED_UNICODE as of PHP 5.4.
  • JSON will have no memory of what the object's original class was (they are always restored as instances of stdClass).
  • You can't leverage __sleep() and __wakeup() with JSON
  • Only public properties are serialized with JSON
  • JSON is more portable
  • 默认情况下, json_encode() 将 UTF-8 字符转换为 Unicode 转义序列,而 serialize() 不会。注意:要保持 UTF-8 字符不变,您可以从 PHP 5.4 开始使用选项 JSON_UNESCAPED_UNICODE。
  • JSON 不会记住对象的原始类是什么(它们总是作为 stdClass 的实例恢复)。
  • 你不能在 JSON 中利用 __sleep() 和 __wakeup()
  • 仅使用 JSON 序列化公共属性
  • JSON 更便携

But if none of these things are an issue for your use case. it's 100-150% faster than serialize(). (Your Google_Client() class will be converted to a standard class when you decode the string).

但是,如果这些事情都不是您的用例的问题。它比 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...