Related
I'm creating an excel file with a bunch of different data points from information that I'm scraping off the web with Python.
One of those data points is a nested array, which is becoming a string when either it's inserted into the CSV file or read from the PHP file on my server.
The whole idea behind using the nested array is so that I can insert each pair of images and thumbnails into their respective columns in a single row on a separate MySQL table.
Nested Array
images_and_thumbnails = [
['https://images-na.ssl-images-amazon.com/images/I/615JCt72MXL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41rExpVS75L._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71Ss5tJW-4L._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41RpAwvZJ5L._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/6157znz2BeL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41mSje9rDSL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/815wlLde-gL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/51jty5d4BpL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71D2gVlCUOL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41kCBJYI%2BCL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71EfsMWdx0L._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41utl4%2B%2B%2BoL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/61m4mFpIvVL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41S27BGn0UL._US40_.jpg']
]
PHP Script to Process the Excel File
$str2 = 'INSERT INTO deals_images_and_thumbnails (asin, image, thumbnail) VALUES (:asin, :image, :thumbnail)';
$sta2 = $conn->prepare($str2);
$file = fopen($_SESSION['file'], 'r');
while (!feof($file)) {
while($row = fgetcsv($file)) {
if (count($row) === 31) {
$images_and_thumbnails = $row[8];
foreach ($images_and_thumbnails as $value) {
$sta2->execute([
'asin' => $asin,
'image' => $value[0],
'thumbnail' => $value[1]
]);
}
The issue is that $images_and_thumbnails is a string, which is obviously "an invalid argument" for the foreach loop.
Is there any way to convert the string back to an array?
Will simply removing the double quotes do the job?
If the format of $images_and_thumbnails is fixed, you could use explode to split it up:
$images_and_thumbnails = "[
['https://images-na.ssl-images-amazon.com/images/I/615JCt72MXL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41rExpVS75L._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71Ss5tJW-4L._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41RpAwvZJ5L._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/6157znz2BeL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41mSje9rDSL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/815wlLde-gL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/51jty5d4BpL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71D2gVlCUOL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41kCBJYI%2BCL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71EfsMWdx0L._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41utl4%2B%2B%2BoL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/61m4mFpIvVL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41S27BGn0UL._US40_.jpg']
]";
foreach (explode('],', $images_and_thumbnails) as $i_and_t) {
$value = explode("', '", trim($i_and_t, "[]' \t\r\n"));
print_r($value);
}
However if it can be variable with spacing, it is better to use preg_split:
foreach (preg_split('/\'\s*\]\s*,\s*\[\s*\'/', $images_and_thumbnails) as $i_and_t) {
$value = preg_split('/\'\s*,\s*\'/', trim($i_and_t, "[]' \t\r\n"));
print_r($value);
}
If you're 100% certain that the data is safe, you could also eval it i.e.
eval ("\$images_and_thumbnails = [
['https://images-na.ssl-images-amazon.com/images/I/615JCt72MXL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41rExpVS75L._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71Ss5tJW-4L._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41RpAwvZJ5L._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/6157znz2BeL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41mSje9rDSL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/815wlLde-gL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/51jty5d4BpL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71D2gVlCUOL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41kCBJYI%2BCL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71EfsMWdx0L._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41utl4%2B%2B%2BoL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/61m4mFpIvVL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41S27BGn0UL._US40_.jpg']
];");
print_r($images_and_thumbnails);
Any of those methods will give you the same result:
Array (
[0] => https://images-na.ssl-images-amazon.com/images/I/615JCt72MXL._UY575_.jpg
[1] => https://images-na.ssl-images-amazon.com/images/I/41rExpVS75L._US40_.jpg
)
Array (
[0] => https://images-na.ssl-images-amazon.com/images/I/71Ss5tJW-4L._UY575_.jpg
[1] => https://images-na.ssl-images-amazon.com/images/I/41RpAwvZJ5L._US40_.jpg
)
Array (
[0] => https://images-na.ssl-images-amazon.com/images/I/6157znz2BeL._UY575_.jpg
[1] => https://images-na.ssl-images-amazon.com/images/I/41mSje9rDSL._US40_.jpg
)
Array (
[0] => https://images-na.ssl-images-amazon.com/images/I/815wlLde-gL._UY575_.jpg
[1] => https://images-na.ssl-images-amazon.com/images/I/51jty5d4BpL._US40_.jpg
)
Array (
[0] => https://images-na.ssl-images-amazon.com/images/I/71D2gVlCUOL._UY575_.jpg
[1] => https://images-na.ssl-images-amazon.com/images/I/41kCBJYI%2BCL._US40_.jpg
)
Array (
[0] => https://images-na.ssl-images-amazon.com/images/I/71EfsMWdx0L._UY575_.jpg
[1] => https://images-na.ssl-images-amazon.com/images/I/41utl4%2B%2B%2BoL._US40_.jpg
)
Array (
[0] => https://images-na.ssl-images-amazon.com/images/I/61m4mFpIvVL._UY575_.jpg
[1] => https://images-na.ssl-images-amazon.com/images/I/41S27BGn0UL._US40_.jpg
)
Demo on 3v4l.org
As single call of preg_match_all() with the PREG_SET_ORDER flag will set up a multidimensional array that will make isolating your desired data a snap. Furthermore, if you wanted to perform validation on the input data, you could write a more strict pattern to ensure you are getting valid jpg strings.
If this was my task and I had no control over the format of the input data, this is how I would parse it. One call does it all.
Code: (Demo) (Regex Demo)
$string = <<<STRING
images_and_thumbnails = [
['https://images-na.ssl-images-amazon.com/images/I/615JCt72MXL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41rExpVS75L._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71Ss5tJW-4L._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41RpAwvZJ5L._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/6157znz2BeL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41mSje9rDSL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/815wlLde-gL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/51jty5d4BpL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71D2gVlCUOL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41kCBJYI%2BCL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/71EfsMWdx0L._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41utl4%2B%2B%2BoL._US40_.jpg'],
['https://images-na.ssl-images-amazon.com/images/I/61m4mFpIvVL._UY575_.jpg', 'https://images-na.ssl-images-amazon.com/images/I/41S27BGn0UL._US40_.jpg']
]
STRING;
if (preg_match_all("~\s*\['([^']*)',\s*'([^']*)']~", $string, $out, PREG_SET_ORDER)) {
foreach ($out as $row) {
var_export($row); // to demonstrate what is generated
$image = $row[1]; // for your actual usage
$thumbnail = $row[2]; // for your actual usage
echo "\n---\n";
}
}
Output:
array (
0 => ' [\'https://images-na.ssl-images-amazon.com/images/I/615JCt72MXL._UY575_.jpg\', \'https://images-na.ssl-images-amazon.com/images/I/41rExpVS75L._US40_.jpg\']',
1 => 'https://images-na.ssl-images-amazon.com/images/I/615JCt72MXL._UY575_.jpg',
2 => 'https://images-na.ssl-images-amazon.com/images/I/41rExpVS75L._US40_.jpg',
)
---
array (
0 => ' [\'https://images-na.ssl-images-amazon.com/images/I/71Ss5tJW-4L._UY575_.jpg\', \'https://images-na.ssl-images-amazon.com/images/I/41RpAwvZJ5L._US40_.jpg\']',
1 => 'https://images-na.ssl-images-amazon.com/images/I/71Ss5tJW-4L._UY575_.jpg',
2 => 'https://images-na.ssl-images-amazon.com/images/I/41RpAwvZJ5L._US40_.jpg',
)
---
array (
0 => ' [\'https://images-na.ssl-images-amazon.com/images/I/6157znz2BeL._UY575_.jpg\', \'https://images-na.ssl-images-amazon.com/images/I/41mSje9rDSL._US40_.jpg\']',
1 => 'https://images-na.ssl-images-amazon.com/images/I/6157znz2BeL._UY575_.jpg',
2 => 'https://images-na.ssl-images-amazon.com/images/I/41mSje9rDSL._US40_.jpg',
)
---
array (
0 => ' [\'https://images-na.ssl-images-amazon.com/images/I/815wlLde-gL._UY575_.jpg\', \'https://images-na.ssl-images-amazon.com/images/I/51jty5d4BpL._US40_.jpg\']',
1 => 'https://images-na.ssl-images-amazon.com/images/I/815wlLde-gL._UY575_.jpg',
2 => 'https://images-na.ssl-images-amazon.com/images/I/51jty5d4BpL._US40_.jpg',
)
---
array (
0 => ' [\'https://images-na.ssl-images-amazon.com/images/I/71D2gVlCUOL._UY575_.jpg\', \'https://images-na.ssl-images-amazon.com/images/I/41kCBJYI%2BCL._US40_.jpg\']',
1 => 'https://images-na.ssl-images-amazon.com/images/I/71D2gVlCUOL._UY575_.jpg',
2 => 'https://images-na.ssl-images-amazon.com/images/I/41kCBJYI%2BCL._US40_.jpg',
)
---
array (
0 => ' [\'https://images-na.ssl-images-amazon.com/images/I/71EfsMWdx0L._UY575_.jpg\', \'https://images-na.ssl-images-amazon.com/images/I/41utl4%2B%2B%2BoL._US40_.jpg\']',
1 => 'https://images-na.ssl-images-amazon.com/images/I/71EfsMWdx0L._UY575_.jpg',
2 => 'https://images-na.ssl-images-amazon.com/images/I/41utl4%2B%2B%2BoL._US40_.jpg',
)
---
array (
0 => ' [\'https://images-na.ssl-images-amazon.com/images/I/61m4mFpIvVL._UY575_.jpg\', \'https://images-na.ssl-images-amazon.com/images/I/41S27BGn0UL._US40_.jpg\']',
1 => 'https://images-na.ssl-images-amazon.com/images/I/61m4mFpIvVL._UY575_.jpg',
2 => 'https://images-na.ssl-images-amazon.com/images/I/41S27BGn0UL._US40_.jpg',
)
---
This question already has answers here:
find the filename from a string with php
(3 answers)
Closed 7 years ago.
I have a .csv file which I have converted into an array $outputData. The 6th $data[6] element of each array contains an image file path, e.g.
http://images.pleaserusa.com/pic/unique.image.jpg
I need to remove the the filepath http://images.pleaserusa.com/pic/ of each image and leave just the image name itself, e.g.
unique.image.jpg
I have looked on here and Google and tried to use preg_match() and str* functions, but I'm not really getting anywhere with it.
Rizer123 I have placed the "basename" function but can't get it to replace inside the element . i can only get it to echo/print outside the array / i have placed the code below and an excerpt array out put below .
domina-456-b.jpgArray
(
[0] => DOM456/B
[1] => 6" Lace-Up Pump W/ D-Ring&Ribbon Lace
[2] => Devious
[3] => Single Soles
[4] => DOMINA-456
[5] => Blk Pat
[6] => http://images.pleaserusa.com/pic/domina-456-b.jpg
[7] => 5-15
)
domina-460-b.jpgArray
(
[0] => DOM460/B
[1] => 6" Oxford Lace Up Pump
[2] => Devious
[3] => Single Soles
[4] => DOMINA-460
[5] => Blk Pat
[6] => http://images.pleaserusa.com/pic/domina-460-b.jpg
[7] => 5-16
)
<?php
$input = 'Parser/Inv_item.csv';
$output = 'hd_inv_items.csv';
if (false !== ($ih = fopen($input, 'r'))) {
$oh = fopen($output, 'w');
header('Content-Type: text/plain');
while (false !== ($data = fgetcsv($ih))) {
// this is where you build your new row
$outputData = array($data[0], $data[1], $data[2], $data[3], $data[5],$data[6], $data[9], $data[8]);
$path = $data[9];
$name = basename($path); // $name == '1.jpg'
print_r($name);
print_r($outputData);
//fputcsv($oh, $outputData);
}
fclose($ih);
fclose($oh);
}
?>
As you can see the image file path is still in the array and the basename result is printing outside of the array . How do i fix this issue
Regards Biwwabong
No need for explosions or string manipulations for this, a simple basename() should suffice:
$path = 'http://images.pleaserusa.com/pic/unique.image.jpg';
echo basename($path);
output:
unique.image.jpg
pathinfo() would work as well:
echo pathinfo($path, PATHINFO_BASENAME);
I always do this with explode()
$url = "http://images.pleaserusa.com/pic/unique.image.jpg";
$parts = explode("/",$url);
$pic = $parts[count($parts)-1];
You are welcome ;-)
I'm trying to do a simple PHP function to put a .csv file into a database. The problem is that the files are delimited with a semicolon and for some reason when a cell contains a comma it leaves out everything after it.
For example the .csv file
manufacturer;comment;year
toyota;good car, bad color;1997
comes out as the following when printed with the print_r() function
[0] => Array
(
[0] => manufacturer
[1] => comment
[2] => year
)
[1] => Array
(
[0] => toyota
[1] => good car
)
Edit
Here's the code I'm using.
//get the contents of the .csv file
$filepath = './files/csvfile.csv'
$fileopen = fopen($filepath,"r");
//create an empty array
$csv = array();
//go through the .csv file with fgetcsv()
while(($line = fgetcsv($fileopen,";")) !== FALSE)
{
$line = explode(";",$line[0]);
$csv[] = $line;
}
//print the result
echo "<pre>";
print_r($csv);
echo "</pre>";
fclose($fileopen);
Put the delimiter as the 3rd argument
http://php.net/manual/en/function.fgetcsv.php
while(($line = fgetcsv($fileopen, 0, ";")) !== FALSE)
I don't think you need that explode line either.
this could have been asked over and over again but i have failed to get the best answer allover google. Please help me.
Problem
Am fetching data from a forex rates rest API and this is exactly how the reply looks when i print it out.
EUR/USD,1380039070258,1.34,868,1.34,873,1.34641,1.35193,1.34932
USD/JPY,1380039068699,98.,789,98.,797,98.471,99.180,98.838
GBP/USD,1380039067482,1.60,082,1.60,095,1.59546,1.60500,1.60419
EUR/GBP,1380039067816,0.84,245,0.84,256,0.84067,0.84495,0.84127
USD/CHF,1380039064893,0.91,161,0.91,172,0.90974,0.91338,0.91097
EUR/JPY,1380039066371,133.,236,133.,252,132.697,134.008,133.371
EUR/CHF,1380039063317,1.22,951,1.22,966,1.22853,1.23050,1.22919
USD/CAD,1380039062062,1.02,960,1.02,969,1.02655,1.03111,1.02841
AUD/USD,1380039069019,0.93,957,0.93,968,0.93635,0.94329,0.94307
GBP/JPY,1380039066561,158.,149,158.,170,157.342,158.978,158.552
Note that each line contains comma delimited data and the next line is on the next line.
When i store this data in a response variable $resp and use the code below
$result=str_getcsv($resp, "\n");
pr($result);
I get the expected result as below
Array
(
[0] => EUR/USD,1380039070258,1.34,868,1.34,873,1.34641,1.35193,1.34932
[1] => USD/JPY,1380039068699,98.,789,98.,797,98.471,99.180,98.838
[2] => GBP/USD,1380039067482,1.60,082,1.60,095,1.59546,1.60500,1.60419
[3] => EUR/GBP,1380039067816,0.84,245,0.84,256,0.84067,0.84495,0.84127
[4] => USD/CHF,1380039064893,0.91,161,0.91,172,0.90974,0.91338,0.91097
[5] => EUR/JPY,1380039066371,133.,236,133.,252,132.697,134.008,133.371
[6] => EUR/CHF,1380039063317,1.22,951,1.22,966,1.22853,1.23050,1.22919
[7] => USD/CAD,1380039062062,1.02,960,1.02,969,1.02655,1.03111,1.02841
[8] => AUD/USD,1380039069019,0.93,957,0.93,968,0.93635,0.94329,0.94307
[9] => GBP/JPY,1380039066561,158.,149,158.,170,157.342,158.978,158.552
[10] =>
)
This works perfectly on my localhost server but when i deploy it, i get an error below
Call to undefined function str_getcsv()
It seams the server doesn't know about that str_getcsv() function i tried to use.
I tried to use other functions like fgetcsv() but cant get them to give me the array output i want.
below is how i used fgetcsv()
$fh = fopen('php://memory', 'rw');
fwrite($fh, $resp);
rewind($fh);
$result = fgetcsv( $fh, strlen($resp), ',', ' ');
fclose($fh);
pr($result);
but it picks only the first line of the $resp string and here is the output it gives
Array
(
[0] => EUR/USD
[1] => 1380040007538
[2] => 1.34
[3] => 882
[4] => 1.34
[5] => 890
[6] => 1.34641
[7] => 1.35193
[8] => 1.34932
)
yet i want all the lines of the $resp string indexed in the array like in the first array
Please if you can help me get this to work by converting the string to the desired array, thanks inadvance.
You can use explode("\n", $resp) to get array of lines.
People are right when they tell you to check the documentation or Google. Developing software is not just about typing code but also a good part of reading and research.
The error your server produces is very likely because you run an ancient php version and should update it - security is a keyword here as well. Because this function http://php.net/manual/en/function.str-getcsv.php is supported since 5.3.
Further the first comment there includes an example of how to archive the same thing without that function:
function csv_to_array($filename='', $delimiter=',')
{
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
{
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
I have not tested it, that's your job.
The comment after that has an even more detailed replacement if the function is missing.
I am fairly new to php and got this from a stack overflow question and cant seem to get it to work for me.
<?php
if (($handle = fopen("fullbox.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
echo "<pre>".print_r($data)." <br /></pre>";
}
fclose($handle);
}
echo $data[1];
?>
I need to set up a couple arrays for pricing using a large number of products(which I can pull from my csv file) Fullbox.csv consists of just 10 numbers with 2 decial places. I have just been trying to test this and this is the output that I get:
Array
(
[0] => 8.53
)
Array
(
[0] => 4.74
)
Array
(
[0] => 5.00
)
Array
(
[0] => 2.50
)
Array
(
[0] => 6.48
)
Array
(
[0] => 3.99
)
Array
(
[0] => 8.53
)
Array
(
[0] => 4.74
)
Array
(
[0] => 8.53
)
Array
(
[0] => 4.74
)
Why is the array setting all values in the [0} place holder of the array and also why is there a 1 in between each line. Thanks in advance.
Update If this is a ten item array this should then return the value of the 1 entry in the array but it doesn't. I essentially just need to store all of the prices so I can use them as variables later. I don't need them to be printed. Thanks again.
echo $data[1];
print_r does not return the formatted array by default; it outputs it and returns 1. Pass true as a second parameter.
echo "<pre>".print_r($data, true)." <br /></pre>";
All the values are in the 0 index of the array because arrays start at 0. There is nothing wrong there.
Try this:
$f = fopen(yourfile, "r");
$fs = filesize(yourfile);
$content = fread($f, $fs);
$lines = explode("\n", $content);
$result = array();
foreach($lines as $line) $result[] = explode(",", $line);
CSV as in Comma Seperated-Values is an array each line. So each line -even if it has only 1 value- is array.
Also you don't need to echo "print_r".
you also read the data from the CSV using the following function and sort using the usort() function.
http://www.pearlbells.co.uk/how-to-sort-a1a2-z9z10aa1aa2-az9az10-using-php/
Read data from the CSV
function readCSV() {
$csv = array_map('str_getcsv', file('data.csv'));
array_shift($csv); //remove headers
$csvData = splitandSort($csv);
createCSV($csvData);
}