I have a php file that contains text in the following format.
line 1 - "Title","URL","imgURL","tags"
line 2 - "Title","URL","imgURL","tags"
line 3 - "Title","URL","imgURL","tags"
It is basically structured like a database so each line is a record and 1st set of "" is always a title. 2nd set of "" is always a URL, etc.... line by line.
I'm not an experienced programmer by any stretch of the imagination. What is the best way to create an array from the contents of the file?
I've tried the following, but it didn't work.
$content = array(file_get_contents("path/content.php"));
I believe I need to update the structure of the data and the method I use to create the array, but I'm not sure how. Any help is greatly appreciated.
I want to be able to retrieve title, URL, imgURL, or tags from any line of text, but I don't know how to express that in an array format.
I think I want to be able to request $content[0][1] to get the URL from line1 and $content[1][3] to get the tags from line2.
$file = fopen("path/content.php", "r");
while($content[] = fgetcsv($file, 1000, ","));
You should then be able to access each element as you specified:
echo $content[0][1]; // echos first line, url
The format of your file is called CSV (comma separated values). Using PHP, you can parse a CSV file using the function fgetcsv: http://php.net/manual/en/function.fgetcsv.php
Are you looking for something like this?
/**
* Decodes a full CSV file to an array.
*
* #param string $file File to decode
*
* #throws \Exception
*
* #return array[]
*/
function csv_decode($file) {
$fh = fopen($file, 'r');
if($fh === false)
{
// FIXME: You should replace this with your own exception!
throw new \Exception("Failed to open file '$file' for reading");
}
$rows = [];
while ($row = fgetcsv($fh))
{
$rows[] = $row;
}
return $rows;
}
The format you have encountered is known as CSV (which stands for comma-separated values)
The above function decodes your data to an array with the structure you've described as can be seen from the output of the following snippet when run on your example data:
print_r(csv_decode('values.txt'));
Which outputs:
Array
(
[0] => Array
(
[0] => Title
[1] => URL
[2] => imgURL
[3] => tags
)
[1] => Array
(
[0] => Title
[1] => URL
[2] => imgURL
[3] => tags
)
[2] => Array
(
[0] => Title
[1] => URL
[2] => imgURL
[3] => tags
)
)
Related
Thank you for the response. I will give it a try and update my question, I have my own code but it is a bit messy to show all. My problem is that I do not get the indexes right.
I use:
$products = array();
$lines = file('data_stock.csv', FILE_IGNORE_NEW_LINES);
foreach ($lines as $key => $value)
{
$products[$key] = str_getcsv($value);
}
And I manage to read the data, but this will give me an error:
if ((int)$products[$_sku] > 0 && isset($products[$_sku])) {
Error: Notice: Undefined index: test-product-1 in....
The 'test-product-1' is from the sku column in the csv file
Output from
echo '<pre>';
print_r($products);
echo '</pre>';
gives:
Array
(
[0] => Array
(
[0] => sku
[1] => qty
)
[1] => Array
(
[0] => test-product-1
[1] => 3
)
[2] => Array
(
[0] => test-product-2
[1] => 6
)
[3] => Array
(
[0] => test-product-3
[1] => 30
)
)
I am trying to use a csv file to be imported into the array to replace
$products = [
'test-product-1' => 3,
'test-product-2' => 6,
'test-product-3' => 30
];
But I can not produce the same array when I import from the CSV file, which will cause problems. Examples for CSV to array: http://php.net/manual/en/function.str-getcsv.php
CSV file:
sku,qty
test-product-1,3
test-product-2,6
test-product-3,30
Next step is to extend the script to handle prices. I need to be able to pick up these variables from the CSV file too. And use them inside the for loop.
sku,qty,price,special_price
test-product-1,3,100,50
test-product-2,6,99,
test-product-3,30,500,300
I think the problem is that when you store the row, your storing it indexed by the row number ($key will be the line number in the file). Instead I think you want to index it by the first column of the CSV file. So extract the data first (using str_getcsv() as you do already) and index by the first column ([0])...
$products = array();
$lines = file('data_stock.csv', FILE_IGNORE_NEW_LINES);
foreach ($lines as $value)
{
$data = str_getcsv($value);
$products[$data[0]] = $data;
}
If you want to add the first row as a header and use it to key the data...
$products = array();
$lines = file('data_stock.csv', FILE_IGNORE_NEW_LINES);
$headers = str_getcsv(array_shift($lines));
$products = array();
foreach ( $lines as $value ) {
$data = str_getcsv($value);
$products[$data[0]] = array_combine($headers, $data);
}
The removes the first row of the array using array_shift() and then uses this row in the array_combine() as the keys for each row. With your test data, you would get something like...
Array
(
[test-product-1] => Array
(
[sku] => test-product-1
[qty] => 3
[price] => 100
[special_price] => 50
)
I used following code in my project and its working fine for me.
I used csv_reader PHP library for it.
You have to put this library in your library folder and import it into file where you want to read your csv.
include_once('../csv_reader.php');
$read = new CSV_Reader;
$read->strFilePath = "file_name_with_path";
$read->strOutPutMode = 0; // 1 will show as HTML 0 will return an array
$read->setDefaultConfiguration();
$read->readTheCsv();
$dataArr = array();
$dataArr = $read->arrOutPut;
In $dataArr, i will get the result,
I have this file that I would like to read into a multidimenstional array in php: file. If I take the first set of lines as a first example, I would like the print_r to look something like this:
Array
(
[SiiNunit] => Array
(
[0] => Array
(
[economy] => _nameless.2BB8.4FB8
[economy_data] => Array
[0] => Array
(
[bank] = _nameless.2917.43B0
[player] = _nameless.2813.6928
[companies] = 312
[companies[0]] = company.volatile.euroacres.nurnberg
[companies[1]] = company.volatile.euroacres.erfurt
etc...
Then as another example, further down the file when it is listing all of the jobs like this:
job_offer_data : _nameless.2BD0.8940 {
cargo: null
company_truck: ""
variant: nil
target: ""
expiration_time: nil
urgency: nil
shortest_distance_km: 0
ferry_time: 0
ferry_price: 0
trailer_pos: (0, 0, 0) (1; 0, 0, 0)
trailer_pos_valid: false
license_plate: ""
}
I would like the array to look somethink like this:
[job_offer] => _nameless.2BB8.4FB8
[job_offer_data] => Array
(
[0] => Array
(
[cargo] = null
[company_truck] = ""
[variant] = nill
[target] = ""
etc...
My code at the moment is:
<?php
// Open the file
$fp = #fopen("game.sii", 'r');
// Add each line to an array
if ($fp) {
$array = explode("\n", fread($fp, filesize("game.sii")));
}
print_r($array);
?>
this (as I expected it to) wrote each line of the file into a 1d array however, I would like it to write it to a multidimensional array=.
Even after lots of googling, I just cannot find the solution for how to do this (so I apologise if I have missed something obvious) so I was hoping someone on here could help me.
Thanks in advance,
Marcus
use serialize php function to before write data to the file the write it to the file
and use unserialize php after read data from file
ex :
$str = serialize($array); //then write it to file
$arr = unserialize($str); //after read from file
I'm using the library PHPExcel to read data in an Excel file. The problem I'm having, is that when I use something like:
$obj = PHPExcel_IOFactory::load($file);
$data = $obj->getActiveSheet()->toArray(null,true,true,true);
To load my file and convert its content into an array, I get all the columns and rows of my Excel file in my array even those without any data in them. Is there a method or something in the library PHPExcel to tell it to ignore cells in my Excel sheet that do not contain any data? (Instead of having a bunch of empty associative arrays in my $data)
If your problem is in getting empty columns that go after real data, and you would like to avoid these, you could do something like this:
$maxCell = $sheet->getHighestRowAndColumn();
$data = $sheet->rangeToArray('A1:' . $maxCell['column'] . $maxCell['row']);
This will return array representing only the area containing real data.
I have this solution for my case
$maxCell = $objWorksheet->getHighestRowAndColumn();
$data = $objWorksheet->rangeToArray('A1:' . $maxCell['column'] . $maxCell['row']);
return all rows with all empty string as:
[1] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] =>
[5] =>
[6] =>
[7] =>
[8] =>
[9] =>
[10] =>
[11] =>
[12] =>
[13] =>
)
To remove these empty rows
$data = array_map('array_filter', $data);
will return
[1] => Array
(
)
And this is the finale solution:
$maxCell = $objWorksheet->getHighestRowAndColumn();
$data = $objWorksheet->rangeToArray('A1:' . $maxCell['column'] . $maxCell['row']);
$data = array_map('array_filter', $data);
$data = array_filter($data);
will return an array with only filled rows .. hope that help
No there isn't. The toArray() method returns the first argument (NULL) to represent an empty cell. You can then apply standard PHP array functions such as array_filter() to eliminate empty cells.
foreach($data as $key => &$row) {
$row = array_filter($row,
function($cell) {
return !is_null($cell);
}
);
if (count($row) == 0) {
unset($data[$key]);
}
}
unset ($row);
This will eliminate every cell that is a NULL (empty) value, and every row that comprises nothing but empty cells. It will preserve the array keys, so your array keys will still give you a cell reference.
Note that an cell containing an empty string is not a null cell, so these will be retained, although the array_filter() callback could be modified to remove them as well.
I have a .csv template I'd wish for people to fill up, save it and upload it.
The problem is this, assuming some users would insert hidden line breaks in a row, when using fgetcsv() it would output the row broken by the hidden line breaks.
How can I escape the line break or sanitize my data?
Possible solution:
assume first row is correct, $count = count the number of delimiters until line break, the rebuild the text into an array as long as $count;
but i think the're better options available.
LATER EDIT
Here's the input *IMPORTANT[ ! ] : the data inside the excel file is "fine", it isn't broken, it's a single row!!! saving it as a csv file and opening it in notepad shows the following
asd;"asd
asd
asd";asd;asd
Here's the code
$handle = fopen("file.csv","r");
$data = fgetcsv($handle,";");
while($data = fgetcsv($handle)) {
$array = explode(";",$data[0]);
print_r($array);
}
fclose($handle);
Here's the echoed data
Array ( [0] => asd [1] => "asd ) Array ( [0] => asd ) Array ( [0] => asd" [1] => asd [2] => asd [3] => )
Thanks
it is very easy to test your case and see that there are no broken rows, if fields being properly quoted.
So, a CSV line like this
1,"joe
""Big Coyote""
Hopkins",598600
will be read with not a single problem.
I need to create a simple text file based search engine asap (using PHP)! Basically it has to read files in a directory, remove stop and useless words, index each remaining useful word with how many times it appears in each document.
I guess the pseudo code for this is:
for each file in directory:
read in contents,
compare to stop words,
add each remaining word to array,
count how many times that word appears in document,
add that number to the array,
add the id/name of the file to the array,
also need to count the total amount of words (after useless removal i guess) in the whole file, which im guessing can be done afterwards as long as i can get the file id from that array and then count the words inside....?
Can anyone help, maybe provide a barebones structure? I think the main bit i need help with is getting the number of times each word appears in the document and adding it to the index array...
Thanks
$words=array();
foreach (glob('*') as $file) {
$contents=file_get_contents($file);
$words[$file]=array();
preg_match_all('/\S+/',$contents,$matches,PREG_SET_ORDER);
foreach ($matches as $match) {
if (!isset($words[$file][$match[0]))
$words[$file][$match[0]]=0;
$words[$file][$match[0]]++;
}
foreach ($useless as $value)
if (isset($words[$file][$value]))
unset($words[$file][$value]);
$count=count($words[$file]);
var_dump($words[$file]);
echo 'Number of words: '.$count;
}
Take a look at str_word_count. It counts words, but can also extract them to an array (each value in the array being a word). You can then post-process this array to remove stop words, count occurrences, etc.
Well getting each file in the directory should be simple by using glob
Then reading the files can be done with
file_get_contents
/**
* This is how you will add extra rows
*
* $index[] = array(
* 'filename' => 'airlines.txt',
* 'word' => 'JFK',
* 'count' => 3,
* 'all_words_count' => 42
* );
*/
$index = array();
$words = array('jfk', 'car');
foreach( $words as $word ) {
// All files with a .txt extension
// Alternate way would be "/path/to/dir/*"
foreach (glob("test_files/*.txt") as $filename) {
// Includes the file based on the include_path
$content = file_get_contents($filename, true);
$count = 0;
$totalCount = str_word_count($content);
if( preg_match_all('/' . $word . '/i', $content, $matches) ) {
$count = count($matches[0]);
}
// And another item to the list
$index[] = array(
'filename' => $filename,
'word' => $word,
'count' => $count,
'all_words_count' => $totalCount
);
}
}
// Debug and look at the index array,
// make sure it looks the way you want it.
echo '<pre>';
print_r($index);
echo '</pre>';
When I tested the above code, this is what I got.
Array
(
[0] => Array
(
[filename] => test_files/airlines.txt
[word] => jfk
[count] => 2
[all_words_count] => 38
)
[1] => Array
(
[filename] => test_files/rentals.txt
[word] => jfk
[count] => 0
[all_words_count] => 47
)
[2] => Array
(
[filename] => test_files/airlines.txt
[word] => car
[count] => 0
[all_words_count] => 38
)
[3] => Array
(
[filename] => test_files/rentals.txt
[word] => car
[count] => 3
[all_words_count] => 47
)
)
I think I have solved your question :D Add this to the after the above script and you should be able to sort the count, starting at zero with $sorted and from the highest with $sorted_desc
function sorter($a, $b) {
if( $a['count'] == $b['count'] )
return 0;
return ($a['count'] < $b['count']) ? -1 : 1;
}
// Clone the original list
$sorted = $index;
// Run a custom sort function
uasort($sorted, 'sorter');
// Reverse the array to find the highest first
$sorted_desc = array_reverse($sorted);
// Debug and look at the index array,
// make sure it looks the way you want it.
echo '<h1>Ascending</h1><pre>';
print_r($sorted);
echo '</pre>';
echo '<h1>Descending</h1><pre>';
print_r($sorted_desc);
echo '</pre>';
Here's a basic structure:
Create an $index array
Use scandir (or glob, if you need to only get files of a certain type) to get the files in the directory.
For each file:
Get contents with file_get_contents
Use str_word_count to get array $word_stream of word stream
Create an array $word_array to hold word counts
For each word in $word_stream:
If it is in a $ignored_words array, skip it
If it is not already in $word_array as a key, add $word_array[$word] = 1
If it is already in $word_array, increment $word_array[$word]++
Get the sum of $word_array with array_sum, or the sum of unique words with count; you can add them to $word_array with keys "_unique" and "_count" (which will not be words), if you like
Add the filename as a key to the $index array, with the value being $word_array