I am trying to concatenate words from a file with words from another file. However when I run the script I get a full output of the first file, then the output of the second file, then I see that the execution does not complete so I am stuck in an infinite loop. This is my code:
include 'passgen.txt';
include 'mycharset.txt';
$lines=file('passgen.txt');
$additions=file('mycharset.txt');
foreach($lines as $line){
foreach($additions as $addition){
$newPasswords=$line . $addition;
}
}
file_put_contents('newPasswords.txt', print_r($newPasswords, true));
passgen.txt content example:
stack
5tack
St4ck
...
mycharset.txt content example:
1
1!
2
2!
Expected results of what I am trying to achieve:
stack1
stack1!
stack2
stack2!
5tack1
5tack1!
...
EDIT:
adding full code from Jay answer:
#!/usr/bin/php
<?php
include 'passgen.txt';
include 'mycharset.txt';
$lines=file('passgen.txt');
$additions=file('mycharset.txt');
foreach($lines as $start) {
foreach($additions as $end) {
file_put_contents('newPasswords2.txt', $start.$end ."\r\n", FILE_APPEND);
}
}
?>
SAMPLE OUTPUT from Jay answer:
St4ck
6!3
St4ck
6!4
St4ck
6!5
I tried to remove the \r\n but still does not append the 6!5 to the word in the desired format below:
St4ck6!4
St4ck6!5
...
You are just creating a line, so you will not get an array as $newPasswords is overwritten on each iteration. What I did was place the concatenated words into an array ($word_array). You can then loop through the array easily and place into a text file:
EDIT
Added the trim() function to account for any whitespace characters in the text files we may not be aware of:
$file1 = ['stack','5tack','St4ck'];
$file2 = ['1','1!','2'];
$word_array = array();
foreach($file1 as $start) {
foreach($file2 as $end) {
$word_array[] = trim($start).trim($end);
}
}
print_r($word_array);
Returns:
Array
(
[0] => stack1
[1] => stack1!
[2] => stack2
[3] => 5tack1
[4] => 5tack1!
[5] => 5tack2
[6] => St4ck1
[7] => St4ck1!
[8] => St4ck2
)
Now you can put these in your text file like this:
foreach($word_array as $word) {
file_put_contents('newPasswords.txt', $word."\r\n");
}
Having said that I caution you against using this for password generation for any reason. You're essentially creating a rainbow table based on your comment:
I am using a weak password finder and I need a custom list of password to compare if hashes are weak.
You'd be better off providing the users with a password strength indicator that would encourage them to create strong passwords.
Shortening the process...
You could shorten the process entirely by writing to the file during the loop, which would require no arrays:
foreach($file1 as $start) {
foreach($file2 as $end) {
file_put_contents('newPasswords.txt', trim($start).trim($end) ."\r\n", FILE_APPEND);
}
}
You can use the fgets() function to read from a file line by line. Then you can concatenate that.
So something like:
$count = 0;
while($word = fgets($lines, 4096)){
$word = $word . additions[$count];
echo $word;
$count++;
}
Related
So I trying to check "if text file on server contains word, show it and display his line number" but i only know how to check "if text file contains word". Anybody have sugesstions how to do it? I saw many tutorials but there are about local text files.
For now I have only this function
function readStrLine($str, $n) {
$lines = explode(PHP_EOL, $str);
return $lines[$n-1];
}
But I need line number.
For example I have text file saved on my server. examplesite.com/file.txt with
this content:
ABCDEF
123456
QWERTY
For now program reads content and checks if there is containing word. But I need the number of this line where this word is.
Example:
<?php
$desiredWord = 'apple';
$fileString = file_get_contents('asd.txt');
$lines = explode(PHP_EOL, $fileString);
$results = [];
foreach ($lines as $lineNumber => $line) {
if (strpos($line, $desiredWord) !== false) {
$results[] = ($lineNumber + 1) .":{$line}";
}
}
foreach ($results as $result) {
echo '<pre>' . print_r($result, true) . '</pre>';
}
Input file content:
apple
asdfsdf
vs
werwerwer
llll
hhheeheh
there is an apple on the tree
the tree does not fall far from it's apple
Output:
1:apple
7:there is an apple on the tree
8:the tree does not fall far from it's apple
You can go through on the lines with a foreach. The $lineNumber key contains the line index you are currently reading, and the $line is the string of the current line. The explode function will index your array from 0, so first line index will be 0 when you read it. That's why the + 1 in this line: $results[] = ($lineNumber + 1) .":{$line}";
With the if (strpos($line, $desiredWord) !== false) you are checking if you find the desired word in the given line. If you want only one result you can return here, but if you would like to collect all of the lines where the word can be found, then you store the found lines like this in the $results
Finally you can check the findings with the second foreach, or any other way - depends on your implementation.
So I have two files, formatted like this:
First file
adam 20 male
ben 21 male
Second file
adam blonde
adam white
ben blonde
What I would like to do, is use the instance of adam in the first file, and search for it in the second file and print out the attributes.
Data is seperated by tab "\t", so this is what I have so far.
$firstFile = fopen("file1", "rb"); //opens first file
$i=0;
$k=0;
while (!feof($firstFile) ) { //feof = while not end of file
$firstFileRow = fgets($firstFile); //fgets gets line
$parts = explode("\t", $firstFileRow); //splits line into 3 strings using tab delimiter
$secondFile= fopen("file2", "rb");
$countRow = count($secondFile); //count rows in second file
while ($i<= $countRow){ //while the file still has rows to search
$row = fgets($firstFile); //gets whole row
$parts2 = explode("\t", $row);
if ($parts[0] ==$parts2[0]){
print $parts[0]. " has " . $parts2[1]. "<br>" ; //prints out the 3 parts
$i++;
}
}
}
I cant figure out how to loop through the second file, get each row, and compare to the first file.
You have a typo in the inner loop, you are reading firstfile and should be reading second file. In addition, after exiting inner loop you would want to re-wind the secondfile pointer back to the beginning.
How about this:
function file2array($filename) {
$file = file($filename);
$result = array();
foreach ($file as $line) {
$attributes = explode("\t", $line);
foreach (array_slice($attributes, 1) as $attribute)
$result[$attributes[0]][] = $attribute;
}
return $result;
}
$a1 = file2array("file1");
$a2 = file2array("file2");
print_r(array_merge_recursive($a1, $a2));
It will ouput the following:
Array (
[adam] => Array (
[0] => 20
[1] => male
[2] => blonde
[3] => white
)
[ben] => Array (
[0] => 21
[1] => male
[2] => blonde
)
)
However this one reads both files in one piece and will crash, if they are large ( >100MB). On the other hand 90% of all php programs have this problem, since file() is popular :-)
I have the following code:
$array_test = array();
$file = file_get_contents ('./test.txt');
$file_array = explode("\n", $file);
foreach ($file_array as $line) {
$word = trim($line);
$array_test[] = $word;
}
echo $array_test[0];
if ($array_test[0] == "1") { echo 'first line'; }
echo $array_test[1];
if ($array_test[1] == "2") { echo 'second line'; }
print_r ($array_test);
The test.txt is file encoded in UTF-8. It has 5 lines. On each line I have a number: 1 - first line, 2 - second line, etc.
The result of running the script is as follows:
1
2
second line
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
As you can see there's a problem with the first line. It seems that it was added to the array correctly, but somehow its value differs from "1". There's no problems with the other lines, just the first one.
The problem can be fixed by skipping the first line and starting to add to the array the values from the second line, but I'm just wondering why it doesn't work the way I wrote it?
Usually I don't have any problems with displaying or reading UTF8 encoded texts or pages.
Changing to "file" instead of "file_get_contents" doesn't solve the problem.
Any suggestion would be very appreciated.
p.s. PHP Version 5.3.1
UPDATE: The problem was UTF-8 BOM. See the solution below. Thanks everybody for the help!
The main issue is this but I am not able to solve it yet. On var_dump($array_test[0]) I get the following output:
string '1' (length=4)
This is the reason 'first line' is not echoed as the if condition is not getting true.
Also if you can share your test.txt file it will be easy to catch the problem.
EDIT : Partial Solution
You can add this line before first if condition to handle this behaviour as described by #Tino Didriksen to get your desired output.
$array_test[0] = substr_replace($array_test[0],'',0,3);
(Try doing) -- wrong solution. see below
if($array_test[0] === "1") echo "first line";
and there is one function file() for such cases:
$file = file_get_contents ('./test.txt');
$file_array = explode("\n", $file);
I was WRONG!
var_dump gives us an answer:
string(2) "1
"
there is new line character in the string.
try doing:
$word = trim($line,"\r\n ");
Please try below updated code:
$array_test = array();
$file = file_get_contents ('./test.txt');
$file_array = explode("\n", $file);
foreach ($file_array as $line) {
$word = trim($line);
$array_test[] = $word;
}
echo $array_test[0];
if ($array_test[0][0] == "1") { echo 'first line'; }
echo $array_test[1];
if ($array_test[1][0] == "2") { echo 'second line'; }
I have an array in php that contains all the lines of a text files (each line being one value of the array). My text file had blank lines so the array has blank lines too. I wanted to search the array for a certain value like this:
$array = array();
$lines = file("textfile.txt"); //file in to an array
foreach ($lines as $line)
{
if (stripos($line, "$$") !== false)
{
$array[] = str_replace("$$", "", $line);
}
}
The code above is searching for a $$ and replacing it with a blank. The text file holds a line with a $$1 or any number and I want it to find all instances of that line, which it is doing.
My problem is that I want it to find the next 5 lines that aren't blank after finding the $$(number) and put them into a multi dimensional array. The multidimensional array looking similar to this (the program is a test in case you are wondering why the array is named the way it is):
$test = array(
array('question' => 'What is the answer', 'ansa' => "answera", 'ansb' => "answerb", 'ansc' => "answerc", 'ansd' => "answerd"), // $test[1]
array('question' => 'What is the answer', 'ansa' => "answera", 'ansb' => "answerb", 'ansc' => "answerc", 'ansd' => "answerd"), // $test[2]
);
The next five lines after the $$(number) are a question and four answers that need to go into the array. My code with regxp and searching isn't working so i discarded it.
you can try something like this...
<?php
$lines = array_filter(file('text.txt')); //file in to an array
$questions = array();
// find your starts and pull out questions
foreach ($lines as $k=>$line)
{
if (stripos($line, "$$") !== false)
{
$questions[] = array_slice($lines, $k, 5);
}
}
// dump
var_dump($questions);
See php manual for array_slice
Have you looked at preg_replace_callback?
Something along these lines should work:
<?php
function replace_callback($matches) {
var_dump($matches);
}
preg_replace_callback('/\$\$[0-9]+\s+([^'.PHP_EOL.']+){5}/is', 'replace_callback', file_get_contents('textfile.txt'));
?>
I'm building a script which will open a saved text file, export the contents to an array and then dump the contents in a database. So far I've been able to get the file upload working quite happily and can also open said file.
The trouble I'm having is the contents of the file are variable, they have a fixed structure but the contents will change every time. The structure of the file is that each "section" is seperated by a blank line.
I've used php's file() to get an array ... I'm not sure if there's a way to then split that array up every time it comes across a blank line?
$file = $target_path;
$data = file($file) or die('Could not read file!');
Example output:
[0] => domain.com
[1] => # Files to be checked
[2] => /www/06.php
[3] => /www/08.php
[4] =>
[5] => domain2.com
[6] => # Files to be checked
[7] => /cgi-bin/cache.txt
[8] => /cgi-bin/log.txt
[9] =>
[10] => domain3.com
[11] => # Files to be checked
[12] => /www/Content.js
[13] =>
I know that Field 0 and 1 will be constants, they will always be a domain name then that hash line. The lines thereafter could be anywhere between 1 line and 1000 lines.
I've looked at array_chunk() which is close to what I want but it works on a numerical value, what would be good if there was something which would work on a specified value (like a new line, or a comma or something of that sort!).
Lastly, apologies if this has been answered previously. I've searched the usual places a few times for potential solutions.
Hope you can help :)
Foxed
I think what you're looking for is preg_split. If you just split on a carriage return, you might miss lines that just have spaces or tabs.
$output = array(...);//what you just posted
$string_output = implode('', $output);
$array_with_only_populated_lines = preg_split('`\n\W+`', $string_output);
You could just do something like this. You could change it also to read the file in line-by-line rather than using file(), which would use less memory, which might be important if you use larger files.
$handle = fopen('blah', 'r');
$blocks = array();
$currentBlock = array();
while (!feof($handle)) {
$line = fgets($handle);
if (trim($line) == '') {
if ($currentBlock) {
$blocks[] = $currentBlock;
$currentBlock = array();
}
} else {
$currentBlock[] = $line;
}
}
fclose($handle);
//if is anything left
if ($currentBlock) {
$blocks[] = $currentBlock;
}
print_r($blocks);
Have you tried split('\n\n', $file);
?
You could do it by splitting first on the blank line and then on new lines, e.g.:
$file = $target_path;
$fileData = file_get_contents($file) or die('Could not read file!');
$parts = explode("\n\n", $data);
$data = array();
foreach ($parts as $part) {
$data[] = explode("\n", $part);
}
You could also use preg_split() in place of the first explode() with a regex to sp.lit on lines containing just whitespace (e.g. \s+)
I would use the function preg_grep() to reduce the resulting array:
$array = preg_grep('/[^\s]/', $array);