Это мой код до сих пор
$dataraw = $_SESSION['image'];
$datagambar = json_encode($dataraw);
echo '<pre>';
print_r($dataraw);
echo '</pre>';
print($escaped_json);
$type1 = gettype($dataraw);
print($type1);
$type2 = gettype($datagambar);
print($type2);
Это вывод $dataraw, тип — массив
Array
(
[0] => Array
(
[FileName] => 20221227_202035.jpg
[Model] => SM-A528B
[Longitude] => 106.904251
[Latitude] => -6.167665
)
[1] => Array
(
[FileName] => 20221227_202157.jpg
[Model] => SM-A528B
[Longitude] => 106.9042428
[Latitude] => -6.1676580997222
)
)
Это вывод $datagambar, тип строки
[{"FileName":"20221227_202035.jpg","Model":"SM-A528B","Longitude":106.904251,"Latitude":-6.167665},{"FileName":"20221227_202157.jpg","Model":"SM-A528B","Longitude":106.9042428,"Latitude":-6.167658099722223}]
Перейти на питон
echo shell_exec("D:\Anaconda\python.exe D:/xampp/htdocs/Klasifikasi_KNN/admin/test.py $datagambar");
Это мой Python test.py
import sys, json
import os
import pymysql
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import mplcursors as mpl
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score,hamming_loss,classification_report
json_list = []
escaped_json1 = sys.argv[1]
# this is working but its only a string of array json
# print(escaped_json1)
# this is working but its only a string of array json
json_list.append(json.loads(escaped_json1))
parsed_data = json.loads(escaped_json1)
print(json_list)
print(parsed_data)
Когда я печатаю (escaped_json1), он отображает строку массива json из php ($ datagambar).
Вывод питона:
Hello world has been called [{"FileName":"20221227_202035.jpg","Model":"SM-A528B","Longitude":106.904251,"Latitude":-6.167665},{"FileName":"20221227_202157.jpg","Model":"SM-A528B","Longitude":106.9042428,"Latitude":-6.167658099722223}]
Я использую apache в качестве своего сервера с phpmyadmin и anaconda.
T пытался использовать print(type(escapedjson1)) или print(type(escapedjson1)) но не отображает тип
Json.loads не изменил тип данных на массив python
Как загрузить его и превратить массив строк в массив переменных, чтобы я мог вызвать его и преобразовать в фрейм данных?
Нет, экранирование аргументов не работает, просто заключая их в одинарные кавычки, @RJK. Вы должны сделать это правильно, иначе вы рискуете внедрить код. На самом деле, я бы предпочел такой интерфейс, как pcntl_exec(), где вы не ставите оболочку посередине, но, боюсь, эта функция только для POSIX.
Можете ли вы поделиться результатом print(type(escaped_json1))
@executable ничего не распечатал
Вы должны просто использовать временный файл для передачи ваших данных.
Вам просто нужно заключить в одинарные кавычки аргумент для python:
Shell_exec("python3 test.py '$json'");
Файл.php
$data =
[
[
"FileName" => "20221227_202035.jpg",
"Model" => "27_202035.jpg",
"Longitude" => 106.90425,
"Latitude" => 106.90425
],
[
"FileName" => "20221227_202157.jpg",
"Model" => "SM-A528B",
"Longitude" => 106.9042428,
"Latitude" => -6.1676580997222
]
];
$json = json_encode($data);
// note: arg '$json' is single-quoted
echo shell_exec("python3 test.py '$json'");
Test.py
import sys
import json
from pandas import json_normalize
data = sys.argv[1]
dict = json.loads(data)
df2 = json_normalize(dict)
print(df2)
Выход
FileName Model Longitude Latitude
0 20221227_202035.jpg SM-A528B 106.904251 -6.167665
1 20221227_202157.jpg SM-A528B 106.904243 -6.167658
Видеть: Экранирование двойных кавычек при отправке JSON в качестве аргумента в программе на Python
Кало спасибо за ответ. он не запускал файл python, если я импортировал из pandas.io.json import json_normalize
В file.php ваша переменная $json представляет собой строку, а не массив, как в фактическом вводе, который должен обрабатывать OP.
@Booboo да, это строка массива json, потому что оболочка exec из php не может явно передать массив в python. Если я передам сам $dataraw и не закодирую его сначала в $datagambar, я получу предупреждение: преобразование массива в строку
@calogero Ваш вывод - это то, что я ищу ... я запускаю свой php с сервером apache phpMyAdmin. Когда я пытаюсь импортировать панды только без их использования или делать что-либо еще, php не выполняет файл python с помощью shell_exec..
@JessenJie Вы используете свою строку вместо моей («python3 test.py $json»)?
@calogero, я тоже пробовал ваши строки, они работают так же, как $datagambar.
@calogero json.loads выполняется и может быть распечатан, но вывод по-прежнему представляет собой строки json .. я думаю? потому что я не могу проверить тип с помощью print(type(data))
print(type(dict))
дает <class 'list'>
мне
Давайте продолжим обсуждение в чате.
Как сказал @Booboo, начальный ввод - это массив. Я отредактировал свой ответ, чтобы отразить это. Я надеюсь, что это может помочь.
«Вам просто нужно заключить в одинарные кавычки». Вы тестировали это в Windows? А что произойдет, если строка JSON будет содержать одинарные кавычки?
Обновление: совершенно другой подход
Существует проблема с JSON-кодированием PHP-скрипта структуры для создания строки JSON и последующей передачей ее в качестве аргумента командной строки, поскольку строку необходимо поместить в двойные кавычки, поскольку в закодированной строке могут быть встроенные пробелы. Но сама строка может содержать двойные кавычки в качестве начала строковых символов и внутри такой строки. Смущенный? Кто бы не был?
Однако нет проблем с записью такой строки в файл, а программа Python считывает ее и декодирует. Но мы не хотим иметь дело с временными файлами. Таким образом, решение состоит в том, чтобы передать данные в программу Python, где их затем можно прочитать как стандартный ввод.
Предположим, ваш массив выглядит так:
$arr =
[
[
"FileName" => "\"\\ \nRon's20221227_202035.jpg",
"Model" => "27_202035.jpg",
"Longitude" => 106.90425,
"Latitude" => 106.90425
],
[
"FileName" => "20221227_202157.jpg",
"Model" => "SM-A528B",
"Longitude" => 106.9042428,
"Latitude" => -6.1676580997222
]
];
Обратите внимание, что я немного изменил ваш пример, так что первое поле FileName содержит символ ", символ ', escape-последовательность \n, представляющую символ новой строки, и, наконец, несколько пробелов. Хотя ваш пример не содержит этих символов или какой-либо другой escape-последовательности, я хотел бы иметь возможность обрабатывать такое условие, если оно возникнет. Это решение должно работать с таким вводом.
PHP-файл
<?php
$arr =
[
[
"FileName" => "\"\\ \nRon's20221227_202035.jpg",
"Model" => "27_202035.jpg",
"Longitude" => 106.90425,
"Latitude" => 106.90425
],
[
"FileName" => "20221227_202157.jpg",
"Model" => "SM-A528B",
"Longitude" => 106.9042428,
"Latitude" => -6.1676580997222
]
];
// Encode string as JSON:
$json = json_encode($arr);
// Pipe the JSON string to the Python process's stdin and
// read the result from its stdout:
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w") // stdout is a pipe that the child will write to
);
$options = array('bypass_shell' => True); // Only has effect on Windows
//$process = proc_open("python3 test.py", $descriptorspec, $pipes, null, null, $options);
// For your actual environment:
$process = proc_open("D:/Anaconda/python.exe D:/xampp/htdocs/Klasifikasi_KNN/admin/test.py", $descriptorspec, $pipes, null, null, $options);
// Pipe the input for the Python program and close the pipe:
fwrite($pipes[0], $json);
fclose($pipes[0]);
// Read the result from the Python program and close its pipe
$result = stream_get_contents($pipes[1]);
fclose($pipes[1]);
# Now that we have closed the pipes, we can close the process:
$return_code = proc_close($process);
echo "Result from stdin:\n$result\n";
Test.py
import json
import sys
DEBUG = True # for debugging purposes
if DEBUG:
import os
for k, v in sorted(os.environ.items()):
print(k, '->', v, file=sys.stderr)
else:
import numpy as np
import pandas as pd
# Load from stdin:
arr = json.load(sys.stdin)
# print each dictionary of the array:
for d in arr:
print(d)
Отпечатки:
{'FileName': '"\\ \nRon\'s20221227_202035.jpg', 'Model': '27_202035.jpg', 'Longitude': 106.90425, 'Latitude': 106.90425}
{'FileName': '20221227_202157.jpg', 'Model': 'SM-A528B', 'Longitude': 106.9042428, 'Latitude': -6.1676580997222}
Спасибо за ответ. Я все еще изучаю ваш ответ, вы создаете формат, который может работать с json.loads? можно ли изменить мой массив на ваш?
См. мой файл Python выше; он делает json.loads() против переданного аргумента программе. Программа сначала выводит переданный аргумент, который является строкой, затем выводит результат выполнения json.loads() для этой строки, которая является списком Python, и, наконец, код выводит каждый элемент списка, который является словарем Python. Каждая из этих трех операций печати разделена пунктирной линией (см. вывод выше).
«может быть упрощено путем двойного кодирования массива». Вы не должны использовать json_encode() в строке, чтобы избежать ее. Бывает, что работает, но это просто случайность. Он не для этого предназначен.
@Olivier Смотрите обновленный код; это совершенно другой и более надежный подход (во всяком случае, на мой взгляд).
Файловый подход определенно намного лучше (лично я бы просто использовал временный файл). Вы видели примечание на странице proc_open относительно опции bypass_shell? Его использование выглядит более безопасным.
@Olivier Это может быть быстрее, но я не понимаю, как в этом случае это безопаснее. Кстати, это вариант только для Windows. Если бы это имело общее применение, то я мог бы увидеть, как это повлияет на то, было ли расширение аргументов с подстановочными знаками выполнено или нет, например, в Linux. Но быстрее - это хорошо.
@Booboo Сэр, почему, если я импортирую пакеты, отличные от sys и json, php shell_exec не запускает файл python? такие как панды, numpy или matplotlib.
Я добавил импорт для pandas и numpy, и у меня все еще работало. Для загрузки этих больших пакетов требуется время, поэтому ответ не будет возвращаться так быстро. Вы уверены, что это были единственные изменения, которые вы внесли? Возможно, вам нужно опубликовать, как именно выглядел ваш файл Python.
Я обновил ответ последним источником Python, показывающим дополнительный импорт. Я также использую json.load() непосредственно против sys.stdin вместо того, чтобы сначала читать ввод, а затем использовать json.loads(). Эти два способа эквивалентны, но теперь это на одну строку короче.
Вы также можете попробовать запустить python3 test.py из командной строки, а затем ввести [1,2], а затем клавишу ввода, а затем либо Ctrl-Z (Windows), либо Ctrl-D (Linux), чтобы сигнализировать о конце файла. Посмотрите, не выводятся ли какие-либо сообщения об ошибках. Но если вы точно запустите мой код выше, он должен просто распечатать 1 и 2 в отдельных строках.
Я только что заметил, что вы упомянули shell_exec в своем комментарии. В моем обновленном ответе этот вызов не используется. Пожалуйста, перечитайте мой ответ.
@Booboo Вы можете проверить это видео, что при импорте пакетов код не запускается drive.google.com/file/d/1nREl3toV6w0b-nXEOTPNkrjg1BtqL44_/…
Я не могу следить за твоей "демо". Как выглядит ваш PHP-код? Это похоже на мой код выше?
@Booboo Я скопировал точно так же, как твой код
Я не знаю, какое у вас окружение. Вы пробовали запустить это из командной строки с помощью python3 test.py, как я изложил несколько комментариев назад?
Python3 test.py не запускал код Python, я использую базовую среду anaconda. D:\xampp\htdocs\Klasifikasi_KNN>python3 test.py Python не найден; запустить без аргументов для установки из Microsoft Store или отключить этот ярлык в меню «Настройки» > «Управление псевдонимами выполнения приложений». D:\xampp\htdocs\Klasifikasi_KNN>python3 test.py Python не найден; запустить без аргументов для установки из Microsoft Store или отключить этот ярлык в меню «Настройки» > «Управление псевдонимами выполнения приложений».
Вы не можете запустить программу Anaconda Python из командной строки? И как на это подается входной JSON? В вашей демонстрации запущена программа PHP? Моя просьба выше заключалась в том, чтобы вы вводили [1,2} и т. д. только для программы Python, чтобы мы могли видеть любые сообщения об ошибках. Честно говоря, я понятия не имею, что вы делаете в этом видео.
Я имею в виду, что вам явно нужно изменить программу PHP, чтобы она указывала на ваш исполняемый файл Python и исходный код Python, чтобы вы кодировали программу PHP: proc_open("D:\Anaconda\python.exe D:/xampp/htdocs/Klasifikasi_KNN/admin/test.py", etc.)
@Booboo о, да, извините .., прежде чем я изменил его на proc_open("D:\Anaconda\python.exe D:/xampp/htdocs/Klasifikasi_KNN/admin/test.py" и т. д.), потому что раньше с python test.py это не работает
Давайте продолжим обсуждение в чате.
Возможно, оболочка не интерпретирует значение переменной $datagambar как отдельный аргумент, поэтому вы можете увидеть некоторый вывод при печати, но не можете проанализировать, поскольку он может быть недопустимым JSON, вы можете попробовать обернуть переменную в одиночный цитаты: echo shell_exec("D:\Anaconda\python.exe D:/xampp/htdocs/Klasifikasi_KNN/admin/test.py '$datagambar'");