This question already has answers here:
scandir - sort numeric filenames
(3 answers)
Closed 2 years ago.
I am building a website and I am having some issues with directories, files and with the php scandir() function. What i have to do is to take images from a folder and then dynamically create a gallery with the these images. Each image has a number in front of its name (ex. 1,nameimg.jpg; 2,nameimg.jpg ecc.) and the problem is that the array returned from scandir() isn't sorted or, better, it is sorted until i have 9 images but when i try to reach the number ten or above it keeps returning this:
Array (
[0] => 1,ADR19604.jpg
[1] => 10,_MG_9690.jpg
[2] => 11,_MG_9785.jpg
[3] => 2,_MG_9685.jpg
[4] => 3,_MG_9732.jpg
[5] => 4,_MG_9750.jpg
[6] => 5,_MG_9759.jpg
[7] => 6,ADR19551.jpg
[8] => 7,ADR19586.jpg
[9] => 8,ADR19604.jpg
[10] => 9,ADR19608.jpg
)
What can i do this sort the array correctly, even when there are more than 9 files?
If all of your files have a UNIQUE number in front of them, you can resort the array really easily like so:
<?php
$imgData = [
'1,ADR19604.jpg',
'10,_MG_9690.jpg',
'11,_MG_9785.jpg',
'2,_MG_9685.jpg',
'3,_MG_9732.jpg',
'4,_MG_9750.jpg',
'5,_MG_9759.jpg',
'6,ADR19551.jpg',
'7,ADR19586.jpg',
'8,ADR19604.jpg',
'9,ADR19608.jpg',
];
$formattedArray = [];
foreach ($imgData as $key => $value) {
//Extract the identifier
$pieces = explode(',', $value);
$number = $pieces[0];
$imgName = $pieces[1];
$formattedArray[$number] = $imgName;
}
var_dump($formattedArray);
If you have more than one image, with the same identifying number:
// Uses $imgData from first example.
$formattedArray = [];
foreach ($imgData as $key => $value) {
//Extract the identifier
$pieces = explode(',', $value);
$number = $pieces[0];
$imgName = $pieces[1];
$formattedArray[$number][] = $imgName;
}
var_dump($formattedArray);
If you're pulling the data from a database, you could also consider using separating the product ID to it's own column for better ordering.
I am having an issue while reading from the excel sheet. I am getting my barcode values in scientific format in csv.
How do i parse the original value instead of the scientific number ?
Example :
9,96E+12 [In excel]
9960000000000 [I want this in CSV]
I am using fgetcsv function in php to parse the csv file.
while (($row = fgetcsv($handle, 1000, ';')) !== FALSE)
{
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
Output that i am getting :
[0] => Array
(
[code] => FJT8-thr-thrtC2-VSXL
[barcode] => 9960000000000
[amount] => 70
[status] => 1
)
I want the output as
[0] => Array
(
[code] => FJT8-thr-thrtC2-VSXL
[barcode] => 9,96E+12
[amount] => 70
[status] => 1
)
You can use the floatval() and sprintf function to convert it back and forth as long as you convert the "," to "." before you use the number in PHP.
<?php
$start = '9,96E+12';
$str = floatval(str_replace(',','.',$start));
// Proof of concept
echo $start."<br />"; // starting off with 9,96E+12
echo $str."<br />"; // Converted number is 9960000000000
echo sprintf('%.2e',$str); // back to scientific number 9.96e+12
?>
I parsing a license key list in php.
Unfortantly the results are not like expected.
It seems that the problem occurs by the special character '<'.
Would be nice if somebody have an idea of possible solutions.
$file_content = '
HM$WN*G&Z58CY8FPUA
F*QZHZGK#&*#*492&T
JJKXP<GZRPKGS7J!EW
P8ZHZ<GCNNR6X=Z7PW
C6HXQFGJ*Y2+#SDZT9
BYYYMEGMQ73G5K#U7F
P>+F=GG7F*U#<RT!6H
B+ZZYTGX&LF6#6XUXU
X&PHNAGN+X><NZYN#9';
$file_array = preg_split("/\n/", $file_content);
echo '<pre>';
print_r($file_array);
OUTPUT
[0] =>
[1] => HM$WN*G&Z58CY8FPUA
[2] => F*QZHZGK#&*#*492&T
[3] => JJKXP P8ZHZ C6HXQFGJ*Y2+#SDZT9
[6] => BYYYMEGMQ73G5K#U7F
[7] => P>+F=GG7F*U# B+ZZYTGX&LF6#6XUXU
[9] => X&PHNAGN+X>
Your split works as it should be, only thing is that browser converts those symbols to tags and causing that. You can check that by running this (I used htmlentities):
<?php
$file_content = '
HM$WN*G&Z58CY8FPUA
F*QZHZGK#&*#*492&T
JJKXP<GZRPKGS7J!EW
P8ZHZ<GCNNR6X=Z7PW
C6HXQFGJ*Y2+#SDZT9
BYYYMEGMQ73G5K#U7F
P>+F=GG7F*U#<RT!6H
B+ZZYTGX&LF6#6XUXU
X&PHNAGN+X><NZYN#9';
$file_array = preg_split("/\n/", $file_content);
array_map("HTMLescape", $file_array);
function HTMLescape($a) {
echo "<pre>".htmlentities($a)."</pre>";
}
Output:
HM$WN*G&Z58CY8FPUA
F*QZHZGK#&*#*492&T
JJKXP<GZRPKGS7J!EW
P8ZHZ<GCNNR6X=Z7PW
C6HXQFGJ*Y2+#SDZT9
BYYYMEGMQ73G5K#U7F
P>+F=GG7F*U#<RT!6H
B+ZZYTGX&LF6#6XUXU
X&PHNAGN+X><NZYN#9
Moreover, for just splitting this line, as #Marcin Orlowski pointed, you can opt for explode which is faster.
There's no benefit from using preg_split() in your case. Use
$file_array = explode("\n", $file_content);
instead, or if the content is being read from file, just do
$file_array = file($filename, FILE_IGNORE_NEW_LINES);
for the same result.
EDIT
but the result should be look like this
If you mean the output is the same as from your question - yes it is, because it is the correct output. The problem is that you are viewing this in web browser which then may consider <... as part of HTML markup. Add echo '<pre>'; before your print_r() to prevent this or run your script in console.
Your code is working fine with some minor modifications:
<?php
$file_content = <<<'EOT'
HM$WN*G&Z58CY8FPUA
F*QZHZGK#&*#*492&T
JJKXP<GZRPKGS7J!EW
P8ZHZ<GCNNR6X=Z7PW
C6HXQFGJ*Y2+#SDZT9
BYYYMEGMQ73G5K#U7F
P>+F=GG7F*U#<RT!6H
B+ZZYTGX&LF6#6XUXU
X&PHNAGN+X><NZYN#9
EOT;
$file_array = preg_split("/\n/", $file_content);
print_r($file_array);
The obvious output on php cli is:
Array
(
[0] => HM$WN*G&Z58CY8FPUA
[1] => F*QZHZGK#&*#*492&T
[2] => JJKXP<GZRPKGS7J!EW
[3] => P8ZHZ<GCNNR6X=Z7PW
[4] => C6HXQFGJ*Y2+#SDZT9
[5] => BYYYMEGMQ73G5K#U7F
[6] => P>+F=GG7F*U#<RT!6H
[7] => B+ZZYTGX&LF6#6XUXU
[8] => X&PHNAGN+X><NZYN#9
)
Note that to visualize that result in a html displaying browser you have to escape the html specific characters (like < and >). but that has nothing to do with splitting the input string, what your question is about.
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.
Simply, I have a script that allows me to upload a CSV file from a HTML form and save it as an array in PHP. This script is working great, although I require my CSV file to be saved as a multidimensional array.
This is how my CSV file will look:
question1,answer1,answer2,answer3,answer4
question2,answer1,answer2,answer3,answer4
question3,answer1,answer2,answer3,answer4
This is in order on what the elements should be saved as:
uploaded[1][1],uploaded[1][2],uploaded[1][3],uploaded[1][4],uploaded[1][5]
uploaded[2][1],uploaded[2][2],uploaded[2][3],uploaded[2][4],uploaded[2][5]
uploaded[3][1],uploaded[3][2],uploaded[3][3],uploaded[3][4],uploaded[3][5]
This is my working upload script
<?php
if(isset($_POST['savecsv']))
{
$csv_array = Array();
$file = fopen($_FILES['upload_file']['tmp_name'], 'r');
if($file){
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
array_push($csv_array,$line);
}
fclose($file);
}
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
<input type="file" name="upload_file" />
<input type="submit" name="savecsv"/>
</form>
I know that arrays start at a value of 0, although this CSV is a upload version to add questions to my website quiz. The way I have setup the rest of my code will only process from [1][1] upwards. No point going into detail why since that is off topic, but it is just how I require it to be done. Therefore, I believe that all [0]'s should be left blank.
Also, each line will always have 5 elements per line. Never more or never less.
I have searched far and wide online, yet I can't seem to find a suitable answer for this.
All help is greatly appreciated.
What you're currently trying to do is not a good way to approach this problem and I'd recommend changing the rest of your code to use the proper array indexes. However, instead of simply pushing $line to $csv_array, you can do this:
$csv_array[] = array_combine(range(1, count($line)), array_values($line));
Full code:
if(isset($_POST['savecsv']))
{
$file = fopen($_FILES['upload_file']['tmp_name'], 'r');
if($file) {
while (($line = fgetcsv($file)) !== FALSE) {
$csv_array[] = array_combine(range(1, count($line)), array_values($line));
}
fclose($file);
}
}
Output:
Array
(
[0] => Array
(
[1] => question1
[2] => answer1
[3] => answer2
[4] => answer3
[5] => answer4
)
[1] => Array
(
[1] => question2
[2] => answer1
[3] => answer2
[4] => answer3
[5] => answer4
)
[2] => Array
(
[1] => question3
[2] => answer1
[3] => answer2
[4] => answer3
[5] => answer4
)
)
Hope this helps!
Your will need to array_unshift
array_unshift(0, $line);
so your records stats with index 1 and having 0 at the 0 index. also initialized your $csv_array as follows
$csv_array = array(array());