经过很多努力,我发现了一些我无法解释/解决的行为,因此请寻求帮助。在我们的服务器上(使用PHP 7.0.30的 Ubuntu 16.04.5 LTS ),我们正在使用“ httpdocs”之外的一些工具,这些工具使用exec()
进行调用以获取其输出。在这种情况下,它是QRCode生成器。
但是,某些QR码将不会显示。我们从该工具获得了输出(输出PNG数据),但是当我们将其显示为图像时,由于某种原因,它似乎已损坏。
经过大量调试,我发现结果有时与工具的输出相差1或2个字节。
我使用下面的QR码( 12345 )进行了最后一次调试,该QR码是一个240字节的文件。但是,最终输出时,长度似乎是239个字节,所以我们在某个地方丢失了一个字节?
我发现使用exec()
,我们正在创建输出数组。尾随空格(例如\ n)不包含在此数组中,因此implode()可以将数组粘贴回字符串,如下所示:
<?php
$cmd = 'cat qr.png';
$output = array();
$exit_code = 0;
exec($cmd, $output, $exit_code);
if($exit_code === 0)
{
header ("Content-type: image/png;");
print implode(PHP_EOL, $output);
}
die();
但是由于某种原因,在此过程中丢失了一个字节吗?我已经使用shell_exec()
(但这里没有return_var,所以我们无法检查验证过程... )
<?php
$command = 'cat qr.png';
$output = shell_exec($command);
if($output !== null)
{
header ("Content-type: image/png;");
print $output;
}
die();
...并使用passthru()
(,但是这会直接输出内容,这是不希望的。在实际代码中无法进行以下示例中的输出缓冲... < / em>)
<?php
$command = 'cat qr.png';
$return_var = 0;
ob_start();
passthru($command, $return_var);
if($return_var === 0)
{
header ("Content-type: image/png;");
$output = ob_get_clean();
print $output;
}
die();
到目前为止,exec()
函数对我们而言一直运行良好,导致$ return_var AND $输出,但是现在我丢失了字节。我已经尝试了PHP_EOL的一些变体,我们现在使用的是胶水( \ n,\ r和\ n \ r ),但是在前两个行尾,我仍然只有239个字节,最后一个是241个字节,所以1个字节就占了很多。
为什么我在这里丢失一个字节?将$ output-array转换回字符串的正确方法是什么?有没有办法通过内爆数组来获取240字节的输出?还是还有其他我尚未找到的功能来执行将为我提供输出以及return_var的命令?
答案 0 :(得分:2)
根据exec
的手动输入,该函数返回输出的最后一行。尚不清楚最后一行是否也包含为$output
的最后一个元素。
但更重要的是,手册指出:
尾随空格,例如\ n,不包含在此数组中。
我猜想这是数组的每个元素(即输出的每行),但是无论哪种方式,您的空格在这里都是重要的,因为您不处理文本-所有字节都是重要的在这里有意义。请记住,空格不仅仅意味着\n
。例如,它也可以表示\t
或(一个空格)。
如果一行以F\t\n
结尾(大写F或任何其他非空白字符,制表符,然后换行),则两个空白字符都将从结尾处去除。在执行implode
操作时,您可能会将\n
放回原处,但是您永远不会知道被剥离的\t
。
这里要意识到的关键是, exec
希望处理纯文本而不是原始二进制数据。
我建议不要使用cat qr.png
,而是使用base64 qr.png
将二进制数据编码为ASCII字符串,然后使用base64_decode
在PHP中对其进行解码。如果实际上不打算使用cat
,则仍然可以像这样通过base64
通过generate-qr-png |base64
传递QR生成命令的输出:exec
。在这种情况下,不应有任何大的空格,因此.mat-calendar-content {
padding: 0px 0px 8px 0px !important;
outline: 0;
}
.mat-calendar-body-cell-content .mat-calendar-body-selected {
border-radius: 100% !important;
color: orange !important;
}
不会让任何东西蒙住。