I am trying to turn an input file in the form below into a series of objects that can be manipulated.
arabian_sea_area = {
1926 1927 1931 1932 1933 2029 2030
}
gulf_of_aden_sea_area = {
1925 2024 5285 5286
}
sdf
<?php
$all_areas = array();
if (($handle = fopen("area.txt", "r")) == False)
{
die("failed to open file\n");
}
while (($line = fgets($handle)) !== FALSE)
{
if (ctype_alpha($line[0]))
{
$line= explode(" ",$line);
// echo($line[0]."\n");
$area = $line[0];
$IDs = explode(" ", fgets($handle));
$IDs[0] = ltrim($IDs[0], ' '); // trying to remove tab from first ID
$all_areas[$area] = $IDs;
//array_push($all_areas, $temp);
}
}
//echo("a\n");
print_r($all_areas["arabian_sea_area"]);
//var_dump ($all_areas);
?>
The values print correctly in the commented out debug lines but fail to print anything for the var_dump at the end.
edit: I realize this was unclear, what I was trying to do was create a master "all_areas" array that linked to objects titled the first line (ie. arabian_sea_area etc.) and I could then get at the numerical Ids for each area algorithmically for a later script.
There are many issues with your code:
1-
if (ctype_alpha($line[0]))
{
$line= explode(" ",$line);
//echo($line[0]."\n");
$temp = $line[0];
$temp = new Area;
$temp->filler($line, $handle);
}
you are creating a $temp variable but you forgot to push it to your main array $all_areas. use array_push
2-
var_dump ($arabian_sea_area);
$arabian_sea_area does not exist.
Did you mean to print your main array $all_areas ?
3- Recommendation:
On errors (echo("failed to open file\n");) its recommended to use die("failed to open file\n"); instead of echo. as die will stop the rest of the script from executing.
-- UPDATE --
I edited your code in a way that should work fine:
class Area {
public $area_name;
public $IDs = array();
public function filler($line, $handle) {
$this->area_name = $line[0];
//echo($this->area_name."\n");
$this->IDs = explode(" ", fgets($handle));
//print_r($this->IDs);
}
}
$all_areas = array();
if (($handle = fopen("area.txt", "r")) == False)
{
die("failed to open file\n");
}
while (($line = fgets($handle)) !== FALSE)
{
if (ctype_alpha($line[0]))
{
$line= explode(" ",$line);
// echo($line[0]."\n");
$temp = $line[0];
$temp = new Area;
$temp->filler($line, $handle);
array_push($all_areas, $temp);
}
}
//echo("a\n");
var_dump ($all_areas);
You might wanna update it to remove / filter empty values.
Related
I'm trying to add only last name if first name is same
data.txt
Alice Sandy
Alice Nanami
James Watt
Alice Monica
Johann Gauss
to result.txt
Alice Sandy Nanami Monica
James Watt
Johann Gauss
I try with this code
$resultFile = "result.txt";
$search = "Alice";
$lineNumber = false;
if ($handle = fopen($result, "r")) {
$count = 0;
while (($line = fgets($handle, 4096)) !== FALSE and !$lineNumber) {
$count++;
$lineNumber = (strpos($line, $search) !== FALSE) ? $count : $lineNumber;
$isExist = (strpos($line, $search) !== FALSE) ? "yup" : "no";
}
fclose($handle);
}
if($isExist=="yup"){
$lines = file($resultFile);
$lines[$lineNumber] = $lines[$lineNumber].' '.$lastName;
file_put_contents($result, implode('', $lines));
}else{
$fullName = $firstName.' '.$lastName;
$fileOpen = fopen($result, "a");
fwrite($fileOpen,$fullName);
fclose($fileOpen);
$addBreaker = "\n";
$splResult = new SplFileObject($resultFile, 'a');
$splResult->fwrite($addBreaker);
}
But it give error offset (I'm using PHP 7) and the result is untidy
Alice Sandy Nanami
Monica
James Watt
Johan Gauss
Thanks for help
Another apporach instead of replacing lines would be save every line to an array and then iterate over array and save to the new file. You can also use the same file as an $outputFile.
$inputFile = 'names.txt';
$outputFile = 'result.txt';
$names = [];
if ($handle = fopen($inputFile, "r")) {
$count = 0;
while (($line = fgets($handle, 4096)) !== FALSE) {
$count++;
$lineNames = explode(' ', $line);
$names[$lineNames[0]][] = trim($lineNames[1]);
}
fclose($handle);
}
$handle = fopen($outputFile, 'w');
foreach ($names as $firstName => $lastNames) {
fwrite($handle, $firstName . ' ' . implode(' ', $lastNames) . PHP_EOL);
}
Two additional notes:
Don't use string as boolean value.
$isExist = (strpos($line, $search) !== FALSE) ? "yup" : "no";
Use just following condition. It's enough
$isExist = (strpos($line, $search) !== FALSE)
If you read lines from file you copy also new lines char, although you can't see them quite well in the output. You should trim all whitespace characters before inserting/replacing etc. to avoid old structure of file.
Use file() to collect the file contents as an array of lines. My snippet starts from there with $lines.
Iterate the array and makes each line modifiable by reference. (&)
Locate the first occurring needle match that not only exists in the line but matches the whole first word so that you don't get false-positive matching.
Then declare the first match as a reference variable (=&) and continue iterating the array. Any subsequent matches will have the delimiting space and second word appended to the reference variable. Then immediate unset the line to be purged from the document.
When done, re-implode the data and stuff the content into the result file.
This is clean, readable, and only needs one loop.
Code: (Demo)
// $lines = file('result.txt', FILE_IGNORE_NEW_LINES);
$lines = [
'Alice Sandy',
'Alice Nanami',
'James Watt',
'Alice Monica',
'Johann Gauss',
'Cooper Alice',
];
$needle = 'Alice';
foreach($lines as $index => &$line) {
if ($needle === strstr($line, ' ', true)) { // check whole first word
if (!isset($firstOccurrence)) {
$firstOccurrence =& $line;
} else {
$firstOccurrence .= strstr($line, ' ');
unset($lines[$index]);
}
}
}
var_export($lines);
// file_put_contents('result.txt', implode(PHP_EOL, $lines));
Output:
array (
0 => 'Alice Sandy Nanami Monica',
2 => 'James Watt',
4 => 'Johann Gauss',
5 => 'Cooper Alice',
)
P.s if you want to know if any rows were changed you could check if the original array is === the new array after looping, or you could just use a boolean flag variable in the else condition.
We have made an array from a text file full of numbers separated by commas, each new line is a new part of the array. (we are not allowed to use explode for this)
We are trying to create a transpose_matrix function to 'transpose' the array now.
Using tutorials on the internet, this is what we have come up with so far, but it doesn't work :(
$myfile = fopen("text1.txt", "r") or die("Unable to open file!");
//echo fread($myfile,filesize("text1.txt"));
$file1 = file("text1.txt");
$store1 = array();
for ($a = 0; $a<count($file1); $a++)
{
array_push($store1, $file1[$a]);
}
for ($k = 0; $k<count($store1); $k++)
{
echo "Line $store1[$k] <br/> END <br/>";
}
function transpose($store1) {
$file1 = file("text1.txt");
$store1 = array();
if (count($store1) == 0) // special case: empty matrix
return array();
else if (count($store1) == 1) // special case: row matrix
return array_chunk($store1[0], 1);
function myCallbackMethod() {
var_dump ($store1);
}
array_unshift($store1, NULL); // the original matrix is not modified because it was passed by value
return call_user_func_array('myCallbackMethod',$store1);
}
transpose($store1);
fclose($myfile);
}
Try reading with fscanf().
something like
fscanf($file_link, '%s\n', $temp);
array_push($array, $temp);
should work.
Sukhdev Mohan
I have a .CSV file with static column names. I receive it daily so i have to automatically edit it on a daily base.
On the first line are the row names for example: row1;row2;row3,row4,row5
for example when i want to unset "row2" and "row4".
How can i unset multiple rows based on a name?
I found a some tutorials about deleting lines or rows based on a row position but nothing that helps me completely.
This is what is have now:
$inFile = 'original.csv';
$outFile = 'edited.csv';
$delimiter = ';';
$enclosure = '"';
$read = fopen($inFile, 'r');
$write = fopen($outFile, 'w');
if ($write && $read) {
while (($data = fgetcsv($read)) !== FALSE) {
// how to unset multiple row names
fputcsv($write, $data, $delimiter, $enclosure);
}
}
fclose($write);
fclose($read);
Also, do i need to use the delimiter and enclosure when i fopen the original file?
Hi you can try the updated following code:
$inFile = 'original.csv';
$outFile = 'edited.csv';
$delimiter = ';';
$enclosure = '"';
$removeFields = array('color');
$write = fopen($outFile, 'w');
if ($write) {
$rows = file($inFile);
$first = false;
foreach($rows as $row) {
$csvToPHP = str_getcsv($row, $delimiter, $enclosure);
if (!$first) {
$headers = array_flip($csvToPHP);
$first = true;
}
foreach($removeFields as $remove) {
unset($csvToPHP[$headers[$remove]]);
}
fputcsv($write, $csvToPHP, $delimiter, $enclosure);
}
}
fclose($write);
I used a test csv original.csv:
name,age,color
test1,20,red
test2,32,blue
test3,92,green
test4,12,red
test5,56,orange
Result edited.csv:
name
test1
test2
test3
test4
test5
Hope it helps. Good luck!
I am creating this array from a posted textarea and splitting the lines:
$ignored = array();
foreach(explode("\n", $_POST["ignored"]) as $ignored2) {
$ignored[] = $ignored2;
echo $ignored2.'<br>';
}
then i have a while loop where i check if any of the array items are in a variable within the while loop:
while(($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
//check if the description is anything in the ignore array
if(in_array($data[6], $ignored)) {
echo 'ignore';
} else {
echo 'dont ignore';
}
}
I put the following in the textarea (one on each line):
SIP Trunk: ST17830T001 (200 channels)
SIP Trunk: ST17830T002 (1 channels)
but its only echoing 'ignore' once and its not ignoring the other item (they both exist in the $data[6] variable
Trim the data from the textarea:
$ignored = array();
foreach(explode("\n", $_POST["ignored"]) as $ignored2) {
$ignored[] = trim($ignored2);
echo $ignored2.'<br>';
}
Also trim the variable you're testing:
if (in_array(trim($data[6]), $ignored)) {
I have the csv file(test.csv) and have the text as below:
1,maly,maly(),f,df
2,cheata,aaa,df,df
3,cheata,df,df,df
4,maly,fc,cfv,f
5,maly,df,fg,fg
6,chantha,fc,gf,fg
7,chantha,gh,a,g
8,David,fgfd,dfg,g
What I want:
I want to diplay only:maly cheata chantha David.For the name that have two or more the same,take only one.And I have the php code as below:
$c=0;
$data=fopen('test.csv','r');
while($row=fgets($data)){
if($c!=0){
echo $row[3]."<br>\n";
}
$c++;
}
The problem is
It does not display what I want. It displays
h h a a h h a
How do I fix this?
Use fgetcsv instead of fgets.
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if (isset($data[1])) {
echo $data[1] . "<br>\n";
}
}
fclose($handle);
}
It looks like you were intending to call fgetcsv instead of fgets. Also, the name index would be 1 then, instead of 3:
<?php
$file = fopen('test.csv', 'r');
while($row = fgetcsv($file)) {
if (isset($row[1])) {
echo $row[1], "\n";
}
}
fclose($file);
The file method returns all lines in an array. The explode method splits up a line by a particular delimiter.
$lines = file($file_name);
$fields = array();
foreach ($lines as $line) {
$cells = explode(',', $line);
$fields[] = $cells[1];
}
echo "<pre>";
print_r($fields);
echo "</pre>";
You're heading does not match your question, you want the second column, not row.
Firstly, your getting the 4th character of each row you need to do something like this (not tested):
$data=fopen('test.csv','r');
while($row=fgets($data)){
$cols = explode(',' $row);
echo $cols[1]."<br>\n";
}