I thought it will be easy task, but simple I'm not able to output data from an array to CSV file (saved on a server).
Code for that part looks like:
$fp = fopen('missing-skus.csv', 'w');
foreach ($missing_array as $lines) {
fputcsv($fp, $lines);
}
fclose($fp);
$missing_array looks like:
Array
(
[0] => 5804
[1] => 5803
[2] => 5802
[3] => 5801
[4] => 5800
[5] => 5799
[6] => 5798
[7] => 5797
[8] => 5796
[9] => 5795
[10] => 5794
[11] => 5793
[12] => 5792
[13] => 5791
[14] => 5790
[15] => 5789
[16] => 5788
[17] => 5787
[18] => 5786
[19] => 5785
[20] => 5784
[21] => 5783
[22] => 5782
[23] => 5781
[24] => 5780
[25] => 5779
)
No matter what, file is always blank. Any clue what I have missed?
The second argument to fputcsv is an array of fields. You are passing a string or integer.
If you want one line with the array values as fields, in CSV fashion, then just:
$fp = fopen('missing-skus.csv', 'w');
fputcsv($fp, $missing_array);
If you just want each array value on one line then no need for fputcsv:
file_put_contents('missing-skus.csv', implode("\n", $missing_array));
Related
i am writing a script to reach out to a website that downloads a csv into cache and then parses the data into an array.
$base_url = "http://www.collincad.org/ccad/propertysearch/download.php?situs_num=1707&situs_street=university&situs_street_suffix=&isd%5B%5D=any&city%5B%5D=any&prop_type%5B%5D=R&prop_type%5B%5D=P&prop_type%5B%5D=MH&active%5B%5D=1&year=2018";
$handle = fopen($base_url, "r");
$flag = true;
while(!feof($handle))
{
$text = fgetcsv($handle, 1024, ",");
if($flag) { $flag = false; continue; }
print $text[1]. " <br>";
}
mysql_close($connect);
When performing the query this way it has the first row and a row of other data and ignores the comma.
$base_url = "export5.csv";
$handle = fopen($base_url, "r");
$flag = true;
while(!feof($handle))
{
$text = fgetcsv($handle, 1024, ",");
if($flag) { $flag = false; continue; }
print $text[1]. " <br>";
}
mysql_close($connect);
but when i manually download the csv file it and read it from the local folder it works as expected... i would prefer not to make this a two step process... im thinking that reading direct from the site with php is the issue, just can figure out how to resolve it.
Thanks
First and foremost when using fopen with a web url, make sure your server is configured to allow it (http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen). Once that is out of the way you should be fine with your code.
The issue though is the CSV format itself.
Looking at the CSV return of that url, its delimiters are tabs, not commas. And I see no enclosures too. So you need to change your fgetcsv to:
$text = fgetcsv($handle, 1024, "\t", '');
And it should begin to return results like this (for each $text):
Array
(
[0] => 15071
[1] => 2018
[2] => P
[3] => Personal
[4] => P-9000-288-0243-1
[5] => N
[6] => ZZZZZZZ BPP # 1707 W UNIVERSITY DR
[7] =>
[8] =>
[9] =>
[10] =>
[11] =>
[12] => BPP AT 1707 W UNIVERSITY DR
[13] => KROGER #488
[14] => 1707
[15] => UNIVERSITY DR
[16] => MCKINNEY
[17] => 1707 W University Dr | McKinney, TX 75069
[18] => 844925
[19] => THE KROGER CO
[20] => CMC
[21] => MCKINNEY CITY
[22] => SMC
[23] => MCKINNEY ISD
[24] =>
[25] => Active
[26] => No
[27] =>
)
Also, the first line in the csv file is this:
Line 1:
Array
(
[0] => sep=
[1] =>
)
So you may want to skip the first TWO lines (the second line being the column headers).
Line 2: (column headers)
Array
(
[0] => Property ID
[1] => Year
[2] => Property Type Code
[3] => Property Type Description
[4] => Geographic ID
[5] => Abstract Or Subdivision Code
[6] => Abstract Or Subdivision Description
[7] => Block
[8] => Tract Or Lot
[9] => Mobile Home Park Code
[10] => Mobile Home Park Description
[11] => Mobile Home Park Space
[12] => Legal Description
[13] => Doing Business As
[14] => Street Number
[15] => Street Name
[16] => City
[17] => Complete Address
[18] => Owner ID
[19] => Owner Name
[20] => Taxing City Code
[21] => Taxing City Name
[22] => Taxing School District Code
[23] => Taxing School District Name
[24] => Market Value
[25] => Property Status
[26] => Certified Data
[27] =>
)
Using cURL:
$url = $some_site;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
where the '$output' variable contains the following 7 columns (# of rows will vary):
1,a,6045,6168,6731,6847,522800
2,b,7847,8124,7645,7716,614400
3,c,7288,7633,7150,7442,801800
4,d,5546,5791,5460,5581,554200
5,e,4579,4679,4359,4572,557400
etc ...
As you can see, in the 4th column, the numbers are:
6168
8124
7633
5791
4679
And the highest number is: 8124
I am trying to figure out how to parse the '$output' variable so I can evaluate all the numbers in the 4th column to determine the high.
I have tried:
$csv = array_map('str_getcsv', $output);
echo max($csv[4]);
But nothing is returned
If you output your $csv value you will see that it is array with structure like:
...
[2] => Array
(
[0] => 3
[1] => c
[2] => 7288
[3] => 7633
[4] => 7150
[5] => 7442
[6] => 801800
)
[3] => Array
(
[0] => 4
[1] => d
[2] => 5546
[3] => 5791
[4] => 5460
[5] => 5581
[6] => 554200
)
[4] => Array
(
[0] => 5
[1] => e
[2] => 4579
[3] => 4679
[4] => 4359
[5] => 4572
[6] => 557400
)
....
So your $csv[4] is not a list of values from column 4. It's the 5th element of your array. So you need to go further, either with a simple foreach:
$max = 0;
foreach ($csv as $row) {
// use index `3` because numeration starts with `0`
if ($max < $row[3]) {
$max = $row[3];
}
}
Or with array_column (since php5.5):
// take all values witn index `3` and find max
echo max(array_column($csv, 3));
In both cases it is 8124
It's because str_getcsv not following standards, and from output You have a "broken array"... I suppose that it may look like this:
Array
(
[0] => 1
[1] => a
[2] => 6045
[3] => 6168
[4] => 6731
[5] => 6847
[6] => 522800
2
[7] => b
[8] => 7847
[9] => 8124
[10] => 7645
[11] => 7716
[12] => 614400
3
[13] => c
[14] => 7288
[15] => 7633
[16] => 7150
[17] => 7442
[18] => 801800
4
[19] => d
[20] => 5546
[21] => 5791
[22] => 5460
[23] => 5581
[24] => 554200
5
[25] => e
[26] => 4579
[27] => 4679
[28] => 4359
[29] => 4572
[30] => 557400
)
http://sandbox.onlinephpfunctions.com/code/b5834d98eda11b1726adc9ef1b7592f9ba32242c
You can do it like this:
<?php
// $csv is just a string ... output from Your curl will be same I think
$csv = <<<EOT
1,a,6045,6168,6731,6847,522800
2,b,7847,8124,7645,7716,614400
3,c,7288,7633,7150,7442,801800
4,d,5546,5791,5460,5581,554200
5,e,4579,4679,4359,4572,557400
EOT;
function csv2array($csv) {
$csv = str_getcsv($csv, PHP_EOL);
return array_map('str_getcsv', $csv);
}
function findMaxInColumn($array, $column = 3) {
return max(array_column($array, $column));
}
$parsedCsv = csv2array($csv);
print_r(findMaxInColumn($parsedCsv));
http://sandbox.onlinephpfunctions.com/code/82020f0d85acf8d6b15b5e7fd78a8d1a80618ff2
I want to scan a directory and add all the file-names to an array in ascending order (numeric, no letters). What appears to be happening is scandir() is sorting them by highest value of the first number and not the whole number. I need to take into account missing text files, so if 9.txt was missing, 10.txt would take its place (no empty spot in array).
Here is the code:
<?php
$array=array();
$int = 1;
$holder=scandir("/postexamples/");
krsort($holder);
foreach($holder as $x)
{
if(!is_dir($x)){
$array[$int]=$x;
$int++;
}
}
echo PHP_EOL . PHP_EOL . "Final array: " , PHP_EOL;
print_r($array);
?>
Which outputs the array:
Array ( [1] => 9.txt [2] => 8.txt [3] => 7.txt [4] => 6.txt [5] => 5.txt [6] => 4.txt [7] => 3.txt [8] => 20.txt [9] => 2.txt [10] => 19.txt [11] => 18.txt [12] => 17.txt [13] => 16.txt [14] => 15.txt [15] => 14.txt [16] => 13.txt [17] => 12.txt [18] => 11.txt [19] => 10.txt [20] => 1.txt )
Is there a better (and preferably working) way to do this? I need it to be like [1] => 1.txt [2] => 2.txt
EDIT:
I need the array to appear like this:
Array ( [1] => 1.txt [2] => 2.txt [3] => 3.txt [4] => 4.txt [5] => 5.txt [6] => 6.txt [7] => 7.txt [8] => 8.txt [9] => 9.txt [10] => 10.txt [11] => 11.txt [12] => 12.txt [13] => 13.txt [14] => 14.txt [15] => 15.txt [16] => 16.txt [17] => 17.txt [18] => 18.txt [19] => 19.txt [20] => 20.txt )
And if one file (for example, 17.txt) was missing, it would look like this:
Array ( [1] => 1.txt [2] => 2.txt [3] => 3.txt [4] => 4.txt [5] => 5.txt [6] => 6.txt [7] => 7.txt [8] => 8.txt [9] => 9.txt [10] => 10.txt [11] => 11.txt [12] => 12.txt [13] => 13.txt [14] => 14.txt [15] => 15.txt [16] => 16.txt [17] => 18.txt [18] => 19.txt [19] => 20.txt )
You need to do a natural sort to get the files in the correct order (20.txt, 10.txt, 2.txt, 1.txt). The function for doing this is natsort.
$sortPath = 'postexamples/';
$files = array();
foreach (scandir($sortPath) as $file) {
if (is_file("$sortPath/$file")) {
$files[] = $file;
}
}
echo PHP_EOL . PHP_EOL . "Final array: " , PHP_EOL;
natsort($files);
$files = array_values($files); // re-key array
print_r($files);
Result
Final array:
Array
(
[0] => 1.txt
[1] => 2.txt
[2] => 4.txt
[3] => 10.txt
[4] => 20.txt
)
Id do it like this.
$files = array_diff(scandir("/postexamples/"), array('.', '..' ));
$array = array();
foreach($files as $file){
if(!is_dir($file)){
$array[]=$file;
}
}
sort($array, SORT_NUMERIC);
You may have to use usort, if it doesn't do the numbers right. Also if you are on php >= 5.4 you may be able to use,
scandir("/postexamples/", SCANDIR_SORT_ASCENDING );
But I haven't tried it. Using sort with numeric flag ( don't forget it's just an array like any other )
$a = Array ( '9.txt', '8.txt', '7.txt', '6.txt', '10.txt', '1.txt');
echo "<pre>";
var_export($a);
echo "<br>";
sort($a, SORT_NUMERIC);
var_export($a);
Result
array (
0 => '9.txt',
1 => '8.txt',
2 => '7.txt',
3 => '6.txt',
4 => '10.txt',
5 => '1.txt',
)
array (
0 => '1.txt',
1 => '6.txt',
2 => '7.txt',
3 => '8.txt',
4 => '9.txt',
5 => '10.txt',
)
So essentially sort($a, SORT_NUMERIC);
Try this ,i hope this will help you:
$ar=array();
$g=scandir("/postexamples/");
krsort($g)
foreach($g as $x)
{
if(is_dir($x))$ar[$x]=scandir($x);
else $ar[]=$x;
}
print_r(sort($ar));
i create a method that will read a file with the application/octet type and here are some of the code.
Raw data :
GTHHS;MEKID Interface;5496;2012-07-20;
NM1;081;IN1;980898989;2001-01-15;Mr;Gaf;Uhkil;Uhkil,Gaf;PRI;Gaf
$contents = file_get_contents($tmp_filename);
$stringContents = explode(";", $contents);
Now it gives me this output :
Array
(
[0] => GTHHS
[1] => MEKID Interface
[2] => 5496
[3] => 2012-07-20
NM1
[4] => 081
[5] => IN1
[6] => 980898989
[7] => 2001-01-15
[8] => Mr
[9] => Gaf
[10] => Uhkil
[11] => Uhkil,Gaf
[12] => PRI
[13] => Gaf
PR1
[14] => 081
[15] => IN1
[16] => 20730089
[17] => 7 The Schooner
[18] => Auhaas
[19] => Huuula Ave
[20] =>
[21] => Kishma
PR2
[22] => 081
[23] => IN1
[24] => 232323233
[25] => 400006
[26] => HGD
[27] => M
[28] => M
[29] => 2007-10-16
[30] => 1976-03-31
);
How can i make the NM1, PR1 as the head of array like this :
Array (
[NM1] = array(
[0] => GTHHS
[1] => MEKID Interface
[2] => 5496
[3] => 2012-07-20
)
);
I am planning also to make the inner array [0]-[3] as json.
If you explode the contents by \n you have each line starting with that identifier. If you then just explode by ; in that line and add it as a sub array, you got it like you want.
This actually looks like a plain old CSV file with your ifentifier in line one. If so, try something like this:
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, ";", "\"", "\n")) !== FALSE)
{
$key = array_shift($row);
$data[$key] = $row;
}
fclose($handle);
}
echo json_encode($data);
http://php.net/manual/en/function.str-getcsv.php
I wrote this piece of code:
$handle = fopen('upload/EFT.csv', "r");
while (! feof($handle)) {
print_r(fgetcsv($handle));
}
fclose($handle);
This is the file:
AKRV0002,AKR,V0002,Akron
AKRV0006,AKR,V0006,Akron
AKRV0007,AKR,V0007,Akron
AKRV0011,AKR,V0011,Akron
AKRV0012,AKR,V0012,Akron
ATLV0019,ATL,V0019,ATLANTA
ATLV0021,ATL,V0021,ATLANTA
It returns this:
Array ( [0] => AKRV0002 [1] => AKR [2] => V0002 [3] => Akron AKRV0006 [4] => AKR [5] => V0006 [6] => Akron AKRV0007 [7] => AKR [8] => V0007 [9] => Akron AKRV0011 [10] => AKR [11] => V0011 [12] => Akron AKRV0012 [13] => AKR [14] => V0012 [15] => Akron ATLV0019 [16] => ATL [17] => V0019 [18] => ATLANTA ATLV0021 [19] => ATL [20] => V0021 [21] => ATLANTA
How can I have this return each line in a new array?
See how array position 3 is "Akron AKRV0006" — that is the last value of line 1 and the first value of line 2. It appears that the newlines aren't being read correctly. Without your raw file, I can't tell why.
Once you have fixed that, you will see that fgetcsv reads only one line at a time (in other words, returns an array with the data from only one row), not all lines at once. So, you will need to loop and add each array to another array until fgetcsv returns no more data:
$data = array();
while ($row = fgetcsv($handle)) {
$data[] = $row;
}
Do you happen to use an old Mac computer?
"Note: If PHP is not properly recognizing the line endings when reading files either on or created by a Macintosh computer, enabling the auto_detect_line_endings run-time configuration option may help resolve the problem."
http://php.net/manual/en/function.fgetcsv.php