how do I pass many php variables to python - php

I am using the following code to initiate a python script and pass a php variable to it.
$tmp = exec("python path/to/pythonfile.py $myVariable $mySecondVariable", $output);
This works very well, my issue is that I will need to pass 100+ variables to the python script. I don't want this exec line to become extremely long and unmanageable. I have also explored passing a php array instead of a variable with the following code:
$checked = array(
"key1" => "1"
"key2" => "1"
"key3" => "1"
);
$checkedJson = json_encode($checked);
$tmp = exec("python path/to/pythonfile.py $myVariable $checkedJson", $output);
With this I have been unable to decode the JSON on the python side. I have been able to do a basic print of the array variable(undecoded) in python, but it gives every individual character as a new array value. ie [0] = k, [1] = e, [2] = y, [3] = 1, etc...
Any help is greatly appreciated.
Just to be clear,I am looking for a simpler method than encoding and decoding an array. Is there a way I can format the exec line to allow for multiple variables.

Store your PHP variables within a temporary text file then use python to read that file.
Simple and effective.
Assuming Scripts are in the same directory
PHP Portion
long version (self contained script - skip to the short version below if you only want the code snippet)
<?php
#Establish an array with all parameters you'd like to pass.
#Either fill it manually or with a loop, ie:
#Loop below creates 100 dummy variables with this pattern.
#You'd need to come up with a way yourself to fill a single array to pass
#$variable1 = '1';
#$variable2 = '2';
#$variable3 = '3';
#....
#$variableN = 'N';
#...
for ($i=1; $i<=100; $i++) {
${'variable'.$i} = $i;
}
#Create/Open a file and prepare it for writing
$tempFile = "temp.dat";
$fh = fopen($tempFile, 'w') or die("can't open file");
#let's say N=100
for ($i=1; $i<=100; $i++) {
#for custom keys
$keyname = 'Key'.$i;
# using a variable variable here to grab $variable1 ... $variable2 ... $variableN ... $variable100
$phpVariablesToPass[$keyname] = ${'variable'.$i} + 1000;
}
#phpVariablesToPass looks like this:
# [Key1] => 1001 [Key2] => 1002 [Key3] => 1003 [KeyN] = > (1000+N)
#now write to the file for each value.
#You could modify the fwrite string to whatever you'd like
foreach ($phpVariablesToPass as $key=>$value) {
fwrite($fh, $value."\n");
}
#close the file
fclose($fh);
?>
or in short, assuming $phpVariablesToPass is an array filled with your values:
#Create/Open a file and prepare it for writing
$tempFile = "temp.dat";
$fh = fopen($tempFile, 'w') or die("can't open file");
foreach ($phpVariablesToPass as $key=>$value) {
fwrite($fh, $value."\n");
}
fclose($fh);
Python Snippet to Grab the Data
lines = [line.strip() for line in open('temp.dat')]
the variable lines now contains all of your php data as a python list.

Related

Export/import mysql json object via CSV

I'm working with a pair of PHP scripts. One script reads data from a MYSQL database and exports it to a csv file then a second script uploads the exported csv file to another MySQL database instance using csv. The structure of the database tables A (export) and B (import) are identical.
These scripts work fine for "normal" MySQL tables and column types. However, the import fails when we apply them to a MySQL table that stores a JSON object in one of the columns (MySQL column type is "json").
The script that exports the data works as expected, producing a CSV file with the JSON object surrounded by double quotes...just like the other values in the row.
The row in the exported CSV file looks like this (the last item is a complex json object, abbreviated for simplicity):
"894","Somebody","Related","2020-02-20","{"name1":"value1","name2":"value2","name3":"value3"}","expired"
In the PHP script to export the data it's essentially this:
$rowStr = "894","Somebody","Related","2020-02-20","{"name1":"value1","name2":"value2","name3":"value3"}","expired";
file_put_contents($filepath, trim($rowStr), FILE_APPEND);
No issues with the export. Row appears in the CSV file as expected (same format as above).
My code to read the csv into the other database looks like this:
$allRows = array_map('str_getcsv',file($fp)); // read the exported csv file where $fp is the path to the file
foreach($allRows as $i => $row) {
//get the col_names from the 2nd database table (identical to the first) where $ac-> is the class that handles data queries
$col_names = $ac->get_table_column_names('databasename',$tablename);
$update_arr = array();
foreach($col_names as $i => $cname) {
$update_arr[$cname['COLUMN_NAME']] = $val;
}
//and write the row to the 2nd db's table
$ac->create_update_table($update_arr,$tablename,FALSE);
}
And, if it matters, here are the Queries used in the "get_table_column_names" and "create_update_table" functions:
get_table_column_names //Using PDO
SELECT COLUMN_NAME,COLUMN_DEFAULT,DATA_TYPE FROM information_schema.columns WHERE table_schema = :db AND table_name = :table
create_update_table
INSERT INTO 'tablename' (field1, field2, field3, field4,json_object_column) VALUES ("894","Somebody","Related","2020-02-20","{"name1":"value1","name2":"value2","name3":"value3"}")
The problem is that, when importing, the row is converted to an array like this:
array (
[0] = "894",
[1] = "Somebody",
[2] = "Related",
[3] = "2020-02-20",
[4] = "{name1":"value1",
[5] = "name2:"value2", //should be part of node 4
[6] = "name3:"value3"}", //should be part of node 4
[7] = "expired"
);
What's happening is that the "," inside the JSON object is being treated as a field separator and the JSON is broken up into array nodes. Other than writing a script to detect fields that start with "{ and end with }", how can I read the entire json string as one field (as it is in the database)? or, perhaps, is there a better way to output the string so that it can be read as one item?
If instead of just writing out the data using something like file_put_contents() you use some of the methods designed for CSV files, this will do most of the work for you...
To write the data use fputcsv() and this escapes the delimiter (in this case the " becomes "")...
$row = ["894","Somebody","Related","2020-02-20",'{"name1":"value1","name2":"value2","name3":"value3"}',"expired"];
$fh = fopen($filepath, "a");
fputcsv($fh, $row);
fclose($fh);
which will write to the file
894,Somebody,Related,2020-02-20,"{""name1"":""value1"",""name2"":""value2"",""name3"":""value3""}",expired
and then to read from the file, just read a line at a time and use fgetcsv()...
$fh = fopen($filepath, "r");
print_r(fgetcsv($fh)); // This in a loop to read all lines
fclose($fh);
which shows
Array
(
[0] => 894
[1] => Somebody
[2] => Related
[3] => 2020-02-20
[4] => {"name1":"value1","name2":"value2","name3":"value3"}
[5] => expired
)
One way of solving this is to create a new copy of the array and manipulate the new array
and add json as a sliced part of the original array.
$allRows = array_map('str_getcsv',file($fp));
$new_arr = [];
foreach($allRows[0] as $key=>$item) {
$json = false;
if (substr($item,0,1) == '{') {
$json_start = $key;
$json = true;
}
if (substr($item,-2,2) == '}"') {
$json_stop = $key;
$json = true;
//Slice json-part from original array (in your case 4,5,6)
$sl = array_slice($allRows[0], $json_start, ($json_stop-$json_start)+1);
//Add the sliced part into key where json started
$new_arr[$json_start] = implode('',$sl);
}
if ($json === false) $new_arr[] = $item;
}
And then you have your expected array in $new_arr.

How do I put a .csv file correctly into an array in PHP?

So I'd like to make a basic login/register page. I got a CSV file which roughly looks like this:
a, b
r,d
login, pass
I am already able to correctly add new combinations to the file. But if I want to put the CSV into an array so that I can check if the username/password combination is true, I only get the first row in the array, so [0] = "a" and [1] = "b". There are similar questions on this site on how to put a csv into an array, but with every solution this problem comes up. How do I get the other elements in the array, too?
Edit: as suggested, the code I used:
$database = fopen("database.csv", "r");
$data = fgetcsv($database, 1000, ",");
print_r($data);
This returns: Array ( [0] => q [1] => w )
Exact data:
q,w
g,h
o,p
t,y
c,d
o,p
o,p
a,b
Hope you can help me.
You can see from the documentation that fgetcsv returns just one line from the file pointer, and NULL or FALSE if it was unable to get another line.
You should put your code in a while loop to get all of the CSV rows.
$credentials = array();
$database = fopen("database.csv", "r");
while (is_array($data = fgetcsv($database, 1000, ','))) {
$credentials[] = $data;
}
fclose($database);
var_dump($credentials); // This contains all of the credentials.

how to read out a value from serialized array stored in a txt-document? php

I just started to do some simple things with php. Now i have a question… 
In this code i open a txt-file and write a key-value-array into it.
At the end I want to read out one value from this array which is stored serialized in the txt-document.
$open = fopen("write/doc.txt", 'w+');
$content = array ("red" => "FF0000", "green" => "#00FF00", "blue" => "#0000FF");
$contentserialized = serialize($content);
fwrite($open, $contentserialized);
fclose($open);
So until now all works properly. And with this code i can show the content of the file:
$file = file_get_contents("write/doc.txt");
echo $file;
But I want only one value out of it. How can I choose for example the value for key "green" on the page?
Would be nice if you can tell me!
echo unserialize($file)['green'];
or if that doesn't work(my php is a little rusty)
$array = unserialize($file);
echo $array['green'];
http://php.net/manual/en/function.unserialize.php
You could load the entire document and parse the content back into a PHP array. That would allow you to work with the data as any other arrays. Something like the following should be enough.
$file = 'write/doc.txt';
$fhandle = fopen($file, 'r');
$content = fread($fhandle, filesize($file));
$content = unserialize($content);
echo $content['green'];
Just as a good practice, remember to close the file handle.
fclose($fhandle);
Hope this helps.
http://php.net/manual/en/function.unserialize.php

Editing PHP using PHP (admin center)

Am developing an admin center where I can edit configuration files (written in PHP). I do NOT want to store these values in a mySQL table (for various reasons). So say my config.php has contents like:
<?php
$option1 = 1;
$option2 = 2;
$option4 = 5;
$option7 = array('test','a','b',c');
?>
Now say in one of the admin pages I will only be changing a few values like option2 or option4 etc. Any ideas on what would be the best way to go about this.
I know one option is to read the PHP file completely and write parts of it using REGEX. Any way to make this more efficent? I don't want the config.php file to break because of some error on the user's end. Any ideas on how to ensure that it works?
If you have some liberty about the way you store configuration values, you may use ini files.
All you have to do is load the content of the ini file in an array with parse_ini_file, then modify values in that array and finally overwrite the file with new values, as described in this comment.
For obvious security reasons it's a good idea to place those files out of your document root.
sample content of ini file :
[first_section]
one = 1
five = 5
animal = BIRD
[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"
sample code (using safefilewrite function) :
<?php
$ini_file = '/path/to/file.ini';
$ini_array = parse_ini_file($ini_file);
$ini_array['animal'] = 'CAT';
safefilerewrite($file, implode("\r\n", $ini_array));
?>
var_export() is probably the function you're looking for.
You can write/read the settings to a file using the following code:
$content = array();
//fill your array with settings;
$fh = fopen ( $bashfile, 'w' ) or die ( "can't open file" );
fwrite ( $fh, $content );
fclose ( $fh );
to read it you use:
file_get_contents() //this will return a string value
OR
Line by line:
$lines = file('file.txt');
//loop through our array, show HTML source as HTML source; and line numbers too.
foreach ($lines as $line_num => $line) {
print "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
}

Is there a function that can read a php function post-parsing?

I've got a php file echoing hashes from a MySQL database. This is necessary for a remote program I'm using, but at the same time I need my other php script opening and checking it for specified strings POST parsing. If it checks for the string pre-parsing, it'll just get the MySQL query rather than the strings to look for.
I'm not sure if any functions do this. Does fopen() read the file prior to parsing? or file_get_contents()?
If so, is there a function that'll read the file after the php and mysql code runs?
The file with the hashes query and echo is in the same directory as the php file reading it, if that makes a difference.
Perhaps fopen reads it post-parse, and I've done something wrong, but at first I was storing the hashes directly in the file, and it was working fine. After I changed it to echo the contents of the MySQL table, it bugged out.
The MySQL Query script:
$query="SELECT * FROM list";
$result=mysql_query($query);
while($row=mysql_fetch_array($result, MYSQL_ASSOC)){
echo $row['hash']."<br>";
}
What I was using to get the hash from this script before, when it was just a list of hashes:
$myFile = "hashes.php";
$fh = fopen($myFile, 'r');
$theData = fread($fh, filesize($myFile));
fclose($fh);
$mystring = $theData;
$findme = $hash;
$pos = strpos($mystring, $findme);
The easiest thing to do would be to modify your first php file which echoes everything, along these lines:
change every instance of echo to e.g. $data[] =
at the bottom, do foreach($data as $d) echo $d (this will produce the same result as you have right now)
you now still have your $data array which you can loop through and do whatever you like with it.
To provide working code examples, it would be great if you could post the current code of your file.
EDIT
If you change your script like so:
$query="SELECT * FROM list";
$result=mysql_query($query);
while($row=mysql_fetch_array($result, MYSQL_ASSOC)){
$data[] = $row['hash']."<br />";
}
foreach($data as $d) {
echo $d;
}
...you'll have the array $data that contains each hash in a key. You can then loop through this array like so:
foreach($data as $d) {
//do something
}

Categories