【问题标题】:Shell_exec returns NULL in PHPShell_exec 在 PHP 中返回 NULL
【发布时间】:2018-12-05 18:28:05
【问题描述】:

我正在做这个项目,需要我在 PHP 上上传图片,在 python 上执行图片,从 python 获取输出并在 PHP 上再次显示。

PHP 代码:

<?php 
$command = shell_exec("python C:/path/to/python/KNNColor.py");
$jadi = json_decode($command);
var_dump($jadi);
?>

Python 代码:

from PIL import Image
import os
import glob
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage import io, color
from scipy.stats import skew

#data train untuk warna
Feat_Mom_M = np.load('FeatM_M.npy')
Feat_Mom_I = np.load('FeatM_I.npy')

Malay_Col_Train = Feat_Mom_M

Indo_Col_Train = Feat_Mom_I

#Data warna
All_Train_Col = np.concatenate((Malay_Col_Train, Indo_Col_Train))

Y_Indo_Col = [0] * len(Indo_Col_Train)
Y_Malay_Col = [1] * len(Malay_Col_Train)

Y_Col_Train = np.concatenate((Y_Malay_Col, Y_Indo_Col))

Train_Col = list(zip(All_Train_Col, Y_Col_Train))

from collections import Counter 
from math import sqrt
import warnings 

#Fungsi KNN
def k_nearest_neighbors(data, predict, k):
   if len(data) >= k:
       warnings.warn('K is set to a value less than total voting groups!')
   distances = []
   for group in data:
      for features in data[group]:
        euclidean_dist = np.sqrt(np.sum((np.array(features) - np.array(predict))**2 ))
        distances.append([euclidean_dist, group])

votes = [i[1] for i in sorted(distances)[:k]]
vote_result = Counter(votes).most_common(1)[0][0]

return vote_result

image_list = []

image_list_pixel = []

image_list_lab = []

L = []
A = []
B = []

for filename in glob.glob('C:/path/to/pic/uploaded/batik.jpg'):
   im=Image.open(filename)
   image_list.append(im)
   im_pix = np.array(im)
   image_list_pixel.append(im_pix)
   #ubah RGB ke LAB
   im_lab = color.rgb2lab(im_pix)
   #Pisah channel L,A,B
   l_channel, a_channel, b_channel = cv2.split(im_lab)
   L.append(l_channel)
   A.append(a_channel)
   B.append(b_channel)
   image_list_lab.append(im_lab)

 <The rest is processing these arrays into color moment vector, it's too long, so I'm skipping it to the ending>

   Feat_Mom = np.array(Color_Moment)

   Train_Set_Col = {0:[], 1:[]}

for i in Train_Col:
    Train_Set_Col[i[-1]].append(i[:-1])

new_feat_col = Feat_Mom

hasilcol = k_nearest_neighbors(Train_Set_Col, new_feat_col, 9)

 import json
 if hasilcol == 0:
    #print("Indonesia")
    print (json.dumps('Indonesia'));
 else:
    #print("Malaysia")
    print (json.dumps('Malaysia'));

如您所见,只有一个打印命令。 Shell_exec 应该从 python 返回打印命令的字符串。但是我在“var_dump”上得到的是NULL,如果我回显$jadi,也什么都没有。无论是使用 print 还是 print(json) 命令

有趣的是,当我尝试从这个 python 文件中显示一个仅包含 1 行代码的字符串时。

Python 虚拟文件:

print("Hello")

“Hello”字符串在我的 PHP 上显示得很好。那么,shell_exec 是不是无法读取很多代码呢?还是我做错了什么?

【问题讨论】:

  • 我会在 $command 上做一个 var_dump 因为 php 的 json_decode 在错误时返回 null 所以 python 可能会输出你所期望的但 json_decode 出错
  • 改用exec(),并捕获退出代码。这是第 1 步。import 语句可能由于缺少环境变量而失败。
  • @Brice 我做了,它仍然显示字符串(0)“”,这意味着空
  • @miken32 我使用了 exec(),它返回了 string(0) :(。导入语句失败可能是原因,但即使是这样,我仍然不知道如何解决它
  • @DerpfaceOnigiri 退出代码 0 应该意味着程序正确执行。尽管从 exec() 函数运行 python 似乎确实有问题。你能在 php 脚本之外成功运行这个 python 脚本吗?

标签: php python shell-exec


【解决方案1】:

我终于找到了背后的原因。在我的 python 脚本中有这些命令:

Feat_Mom_M = np.load('FeatM_M.npy')
Feat_Mom_I = np.load('FeatM_I.npy')

他们加载了我在 KNN 中的训练过程中存储的 numpy 数组,我需要再次将它们用作我在 python 中的图像分类过程的参考。我将它们分开是因为我担心我的 PHP 页面加载时间过长。在最终对上传的图像进行分类之前,它需要处理所有的训练数据。 但是当我从 PHP 执行我的 python 文件时,我猜它在解析这两个加载命令后会返回一个错误。我尝试将打印命令放在它们下面,它停止在 PHP 上显示。既然现在都是这样,没有别的办法,只能选择最坏的选择,即使这会花费我很长时间的加载时间。

【讨论】:

    【解决方案2】:

    我在控制台中对此进行了测试:

    php > var_dump(json_decode("Indonesia"))
    php > ;
    php shell code:1:
    NULL
    php > var_dump(json_decode('{"Indonesia"}'))
    php > ;
    php shell code:1:
    NULL
    php > var_dump(json_decode('{"Indonesia":1}'))
    php > ;
    php shell code:1:
    class stdClass#1 (1) {
      public $Indonesia =>
      int(1)
    }
    php > var_dump(json_decode('["Indonesia"]'))
    php shell code:1:
    array(1) {
      [0] =>
      string(9) "Indonesia"
    }
    

    你必须把它包裹在 {} 或 [] 中,它会被读入一个对象或数组。

    出现错误后,您可以运行此json_last_error()http://php.net/manual/en/function.json-last-error.php,它会给您一个错误代码,您的返回应该是JSON_ERROR_SYNTAX

    【讨论】:

    • 除了json.dumps('Indonesia') 将打印"Indonesia" 所以你真正想做的测试是var_dump(json_decode("\"Indonesia\"")); 这很好。 JSON 可以表示字符串和整数,也可以表示对象和数组。
    • 我做了 var_dump(json_decode('["Indonesia"]')) 仍然返回 NULL
    • 现在我可以从 python 中显示一个 json 文件,但 python 需要直接在命令提示符下执行。如果我尝试从 PHP 执行它,则不会创建 json 文件。我真的认为我的 python 有问题,除了打印命令之外,无法执行所有这些命令,如导入等。
    猜你喜欢
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 2013-02-23
    • 2019-09-10
    • 2016-04-10
    • 1970-01-01
    • 2013-07-07
    相关资源
    最近更新 更多