Creating arrays in a for loop via list()? - php

$$I have a bunch fo text files I'd like to eventually explode into arrays, but since the amount of text files is dynamically chosen via user input, I can't just initialize them one-by-one and instead am opting for a for loop.
For the sake of example, three text files I have contain the following (excuse the \n, imagine it's a line break):
file1.txt = 1 \n 2 \n 3
file2.txt = 6 \n 2 \n 7
file3.txt = 9 \n 1 \n 9
The code I attempted:
<?php
for ($i = 1; $i <= 3; $i++) {
list($line1[$i], $line2[$i], $line3[$i]) = file("public_html/texts/file".$i.".txt");
?>
This obviously doesn't work, but I'm not sure why. In the end, the result should be:
$line1[1] = 1
$line2[1] = 2
$line3[1] = 3
$line1[2] = 6
$line2[2] = 2
$line3[2] = 7
$line1[3] = 9
$line2[3] = 1
$line3[3] = 9
How do I go about doing this?
edit; fixed typo.

You have an error in your code, see:
file("public_html/texts/file".&i.".txt");
^-- TYPO HERE

for($i = 1; $i <= 3; $i++) {
$lines = file('public_html/texts/file' . $i . '.txt');
$line1[] = $lines[0];
$line2[] = $lines[1];
$line3[] = $lines[2];
}

Related

How to read lines of numbers through string? (inside a loop)

I got help from a group user with the previous question, but instead of reading the lines from a txt file, i want to read the lines of numbers from a string.
1 and until 119
How can this be done?
Through txt file it works:
$lines = file("lines.txt");
if($i==119)
...
through string does not.
$numbers = "1
2
4
5
..."
for($i = 119; $i >= 0; $i--)
{
$lines = "$numbers";
if($i==119)
{
$no_of_lines = round(count($lines)/14);
}
$line = $lines["$i"];
echo "$line<br>";
if( $i % 14 === 0 )
{
echo "$no_of_lines<br>";
$no_of_lines--;
}
}
To access your string you either need to know the position in the string where you could use substr but when your numbers get to 10 and beyond the length of 1 digit you can't know the position of each number.
So you could use explode to create an array called $lines delimited by a space (if all your numbers are separated by a space:-
$lines= explode(" ", $numbers);
so then your code could be :-
<?php
$numbers = "1 2 3 4 5 6";
$lines= explode(" ", $numbers);
for($i = 0; $i < count($lines); $i++) {
$line = $lines[$i];
echo "$line<br>";
}
echo "<br>No_of_lines = " . count($lines);
?>
Which gives as your output :-
1
2
3
4
5
6
No_of_lines = 6

adding string after every 'n' number of lines in a file using php

I have a .lst(playlist) file with around 1800 lines of data. Each line contains a URL to an audio file that is being played on my radio station.
The thing is I need to add URLs to some Advertisements after every 'n' number of lines in that file.
There are 10 URLs of advertisements from which 1 URL needs to be added after every 5 lines.
Example: URLs of Advertisements are in this format: file1.mp3, file2.mp3 ... file10.mp3
They will be added like this: file1.mp3 on line 5, file2.mp3 on line 10, file3.mp3 on line 15 and so on. After file10.mp3 has been inserted, it will again start from file1.mp3. I hope you understand.
So far I have managed to cook up the following code, but it only takes up one string to be added and have to manually tell the line number on which the string will be added. Unable to figure out the looping logic to do the aforementioned work.
$url = "/home/station/content/file1.mp3";
$line_number = 5; //add above URL on line number 5
$contents = file('playlist.lst', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if($line_number > sizeof($contents)) {
$line_number = sizeof($contents) + 1;
}
array_splice($contents, $line_number-1, 0, array($url));
$contents = implode("\n", $contents);
file_put_contents('playlist.lst', $contents);
How can I achieve this ?
You can use array_chunk to split your array into $line_number. Then, use array_map() to add your advertisements to each group. Finally, you could reduce to a linear array. You can format the $url using sprintf().
$url = "/home/station/content/file%d.mp3"; // use %d to use using sprintf()
$line_number = 5; //add above URL on line number 5
$counter = 1;
$contents = file('playlist.lst', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// split in group of $line_number
$groups = array_chunk($contents, $line_number);
// for each group:
$groups = array_map(function($arr) use ($url, &$counter) { // pass $counter as reference
// format the link
$adv = sprintf($url, $counter++) ;
// restart to 1 if greater than 10
if ($counter > 10) $counter = 1;
// append to group
$arr[] = $adv;
return $arr ;
},$groups);
// transform to linear array
$contents = array_reduce($groups, 'array_merge', array());
// save new file
file_put_contents('playlist.lst', implode("\n", $contents));
You could do it this way, with a simple loop:
//changing it to a "model" string, we are going to add the correct file number later
$url = "/home/station/content/file";
$contents = file('playlist.lst', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$count = 0;
$AddCount = 1;
//Loop until there is nothing left in our radio list
while ($count < sizeof($contents)) {
//if we have a multiple of 5, we are inserting an ad
if (($count % 5) == 0) {
// to know wich ad to add we use our AddCounter
$tmp = $url . strval($AddCount) . ".mp3";
//As suggested by Justinas, don't forget that each time you had a line you need to also increase the index for the next one using $count%5 to know how many lines you already added
array_splice($contents, $count - 1 + ($count % 5) , 0, array($tmp));
$AddCount += 1;
if ($AddCount > 10)
$AddCount = 1;
}
$count += 1;
}
$contents = implode("\n", $contents);
file_put_contents('playlist.lst', $contents);
This way, you don't even have to handle the advertisements file selection yourself as long as they are all formated like you said.
You should do a loop in such way.
$line_number = 5;
$line_count = 0;
for($i=0; $i < sizeof($contents); $i++)
{
$line_count = $line_count +1; // start with Line 1 that +1
if($line_count == $line_number)
{
// do your magic code of adding a line
$line_count = 0; // refresh counting from the beginning
}
}
You don't need to handle each line in the file one at a time.
Leave the file contents as its original string, inject placeholders with regex, then replace those placeholders with your ad array strings.
Code: (Basic Demo)
$filename = 'playlist.lst';
file_put_contents(
$filename,
vsprintf(
preg_replace(
'/(?:.+(\R)){5}\K/', // match (and forget) 5 lines, capture the newline character
'%s\1', // inject the placeholder following the the newline character
file_get_contents($filename),
count($ads) // make the exact number of needed placeholders
),
$ads // replace the placeholders with the ad strings
)
);

PHP read every 3rd line from file and save it to another file

I want to read every 3rd line from file1 and save it as a new file2.
This is what I am trying, but it doesn't work. Any ideas?
$myfile = file("file1.txt");
$lines = file($myFile);
$newFileContent= $lines[2];
file_put_contents("file2.txt", $newFileContent);
So, if file1.txt has the following content:
1
2
3
4
5
6
The file2.txt should contain only:
3
6
The actual easiest way would be to use a normal for loop. The array is non-associative, so it makes no sense to use an expensive foreach over the entire array.
To exactly replicate your sample data, just use something like the following:
$lines = file('file1.txt');
$newContent = '';
$len = count($lines); // saves us from calling count() on every iteration
for ($i = 2; $i < $len; $i += 3) {
$newContent .= $lines[$i];
}
file_put_contents('file2.txt', $newContent);
Working demo

PHP script to remove all lines of the file except last n lines

How can I remove all the lines except the last n lines of the text file?
What code should I use to remove other lines except for last two lines ?
I have one script which does opposite as this one :
$lines_array = file("./home/userdata/log.ini");
$new_output = "";
for ($i=0; $i<5; $i++){
$new_output .= $lines_array[$i];
}
file_put_contents("./home/userdata/log.ini");
This code will delete all lines except first 5 lines.
Can you improve the above code and write the code that will delete all line except last 5 lines ?
Simply get the number of lines, and use that to know the line numbers for the last two lines:
$lines_array = file("./home/userdata/log.ini");
$lines = count($lines_array);
$new_output = "";
for ($i=$lines-2; $i<$lines; $i++){
$new_output .= $lines_array[$i];
}
file_put_contents("./home/userdata/log.ini", $new_output );
You could do something like
$lines_array = file("./home/userdata/log.ini");
$new_output = array();
$new_output[] = array_pop($lines_array);
$new_output[] = array_pop($lines_array);
$new_output = array_reverse($new_output);
file_put_contents("./home/userdata/log.ini", implode("", $new_output));

Creating files based on the line number for printing

I have following data extracted from the MySQL database to create labels.
BREAK
Name:RAJ
Company:ABC
Order Number:101
Order Details:
Item1
Item20
Item3
BREAK
Name:RAJ
Company:ABC
Order Number:101
Order Details:
2 x Item1
2 x Item2
2 x Item3
BREAK
Name:RAJ
Company:ABC
Order Number:101
Order Details:
5 x Item4
5 x Item5
5 x Item2
I wrote some code to find the position of BREAK in PHP and it can generate lines number like below.
2
14
26
36
I want a file for the contents that are between line 2 and 14 in one file and 26 to 36 in one file. I am working in php and tried using sed from shell_exec function however if I read this output and generate sed command, I don't get first 2 number together.
What I am expecting is below.
sed -n 2,14p file1.txt
sed -n 26,36p file2.txt
Any suggestion either in php or shell script?
Use array_slice() for getting ranges in an array.
My solution is very hard coupled to your requirements, meaning every first line is a starting range number and the following the end range.
// the lines from which will be read
$lines = "1
5
16
26";
// split these numbers above into an array
$lines = explode(PHP_EOL, $lines);
// the source file where the ranges will be taken off
$file = file('file.txt');
for($i = 0; $i < count($lines); $i+=2) {
$rangeStart = $lines[$i];
$rangeLength = $lines[$i+1] - $lines[$i];
// slice out the ranges, beware the second parameter is the length not the offset!
$ranges[] = array_slice($file, $rangeStart, $rangeLength);
}
print_r($ranges);
But it would be a lot easier to do it automatically on your source file/text/string (?) directly, if this is possible.
$file = file('file.txt');
$len = count($file);
$output = array();
$current = array();
for($i = 0; $i < $len; $i++) {
$data = trim($file[$i]);
if ($data != 'BREAK') {
$current[] = $data;
} else {
$output[] = implode(PHP_EOL, $current);
$current = array();
}
}
print_r($output);

Categories