Reputation: 367
This is my code so far
$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);
This is $dataraw output, the type is array
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
)
)
This is $datagambar output, the type is string
[{"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}]
Pass to python
echo shell_exec("D:\Anaconda\python.exe D:/xampp/htdocs/Klasifikasi_KNN/admin/test.py $datagambar");
This is my 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)
When i do print(escaped_json1) it display a string of array json from php($datagambar).
python output:
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}]
I use apache as my server with phpmyadmin and anaconda.
T tried using print(type(escapedjson1)) or print(type(escapedjson1)) but it doesn't display the type
json.loads didn't change the type of data to python array
How to loads it and make the string array into a variable array so i can call it and convert it to dataframe?.
Upvotes: 4
Views: 530
Reputation: 44138
Update: A Completely different approach
There is a difficulty with the PHP script JSON-encoding a structure to produce a JSON string and then passing it as a command line argument since the string needs to be placed in double quotes because there can be embedded spaces in the encoded string. But the string itself can contain double quotes as start of string characters and within such a string. Confused? Who wouldn't be?
There is no problem however with writing such a string to a file and having the Python program read it in and decode it. But we don't want to have to deal with temporary files. So the solution is to pipe the data to the Python program where it can then be read in as stdin
Let's assume your array looks like:
$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
]
];
Note that I have modified your example slightly so that the first FileName
field contains a "
character, a '
character, an escape sequence \n
representing the newline character and finally some spaces. Although your example does not contain these characters or some other escape sequence, I would like to be able to handle such a condition should it arise. This solution should work with such input.
PHP File
<?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)
Prints:
{'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}
Upvotes: 5
Reputation: 53
You just need to enclose in single quotes the argument to python:
shell_exec("python3 test.py '$json'");
file.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)
Output
FileName Model Longitude Latitude
0 20221227_202035.jpg SM-A528B 106.904251 -6.167665
1 20221227_202157.jpg SM-A528B 106.904243 -6.167658
See: Escaping double qoutes when sending JSON as argument in python program
Upvotes: 3