strings comparison in PHP - php

I feel like the biggest fool on the planet earth. But I am looping through a text file and attempting to compare each line and find the line breaks... You know... "\n". But I can't seem to compare the strings!!!!
Here is what I am doing.
$filename = 'StatesCities.txt';
$file = file($filename);
$matchedLines = array();
foreach($file as $line) {
$matchesLines[] = $line;
if(strcmp($line, "La Mesa") == 0)
{
echo("Yeah");
}
echo($line);
echo("<br />");
}

Are you trying to remove the line breaks? If that's the case then you can explode them.
$file = file_get_contents( $file_path );
$page = explode( "\n", $file );
//Now they're gone
foreach( $page as $line )
{
if( strpos( $line, 'searchfor' ) !== false )
{
//do this
}
}
The strpos is how I usually search in a string, just make sure to use !== which checks for false not false or 0. If the string your looking for has a strpos of 0 ( first character ) it would return a false positive if you don't check for the type with !==. Good luck.

Your question says you're looking for "\n" but your code is looking for "La Mesa". Perhaps you wanted to say
if (strpos($line, "\n"))
?

The file() function will maintain newline characters (\n) in the array that it creates by default. See here for more info; in particular, the flags section. To fix your problem...
Instead of this:
$file = file($filename);
Use this:
$file = file($filename, FILE_IGNORE_NEW_LINES);

Related

PHP get file line by line and compare to string

I have a file which is basically a list of names in that format:
name.lastname
name.lastname
name.lastname
myname.mylastname
name.lastname
and I want to check whether a string I have is equal to one of the names (with the dot).
Thats what I tried already:
$username = "myname.mylastname";
$boolean = False;
$handle = fopen("thelist.txt","r");
while (($line = fgets($handle)) !== false) {
if ($line === $username){
$liste = True;
}
}
after that list keeps being False and I dont know why.
Thanks in advance :)
There are a few potential issues I see.
First $boolean = False; while $liste = True;, so you may have a potential typo in your output variable.
Second issue is that thelist.txt is not an absolute path. So the file resource may have failed to be loaded. It is highly recommended that you use an absolute path to file resources such as /full/path/to/file or __DIR__ . '/path/to/file'.
The main issue is that fgets will include the \r and \n at the end of each line in the file, that does not exist in the compared string variable. You can use trim to remove extraneous line endings and white spaces to compare with the string variable.
Example: https://3v4l.org/4VG4D
$username = "myname.mylastname";
$liste = false;
$handle = fopen("thelist.txt", 'rb');
while (false !== ($line = fgets($handle))) {
if (trim($line) === $username){
$liste = true;
break; //stop at first match
}
}
fclose($handle);
var_dump($liste); //true

Php code that returns an array with filenames of files which contains a string

Im trying to make a Php file that receives nothing and checks every file on the folder, searching for a string inside them. it echos a array of filenames that have the string inside. Any way to do it, possibly with low memory usage?
Thank you a lot.
To achieve something like this, I recommend you read about the DirectoryIterator class, file_get_contents, and about strings in PHP.
Here is an example of how you can read the contents of a a given directory ($dir) and use strstr to search for a specific string occurrence in each file's contents ($contents):
<?php
$dir = '.';
if (substr($dir, -1) !== '/') {
$dir .= '/';
}
$matchedFiles = [];
$dirIterator = new \DirectoryIterator($dir);
foreach ($dirIterator as $item) {
if ($item->isDot() || $item->isDir()) {
continue;
}
$file = realpath($dir . $item->getFilename());
// Skip this PHP file.
if ($file === __FILE__) {
continue;
}
$contents = file_get_contents($file);
// Seach $contents for what you're looking for.
if (strstr($contents, 'this is what I am looking for')) {
echo 'Found something in ' . $file . PHP_EOL;
$matchedFiles[] = $file;
}
}
var_dump($matchedFiles);
There is some extra code in this example (adding a trailing slash to $dir, skipping dot files and directories, skipping itself, etc.) that I encourage you to read and learn about.
<?php
$folderPath = '/htdocs/stock/tae';
$searchString = 'php';
$cmd = "grep -r '$searchString' $folderPath";
$output = array();
$files = array();
$res = exec($cmd, $output);
foreach ($output as $line) {
$files[] = substr($line, 0, strpos($line, ':'));
}
print_r($files);

Don't echo things with certain characters

I have a php program that looks at a log file and prints it to a page (code below). I don't want the user of said website to be able to look at any line containing a /. I know I could use trim to delete certain characters, but is there a way to delete the entire line? For example, I want to keep something like "Hello" and delete something like /xx.xx.xx.xx connected. All the lines I wish to delete have the same common key, /. Peoples names in said log file have <>s around them, so I must use htmlspecialcharacters
$file = file_get_contents('/path/to/log', true);
$file = htmlspecialchars($file);
echo nl2br($file);
Thanks for your help!
EDIT:
Thanks for all of the answers, currently tinkering with them!
EDIT2:
final code:
<?php
$file = file_get_contents('/path/to/log', true);
// Separate by line
$lines = explode(PHP_EOL, $file);
foreach ($lines as $line) {
if (strpos($line, '/') === false) {
$line = htmlspecialchars($line . "\n");
echo nl2br($line);
}
}
?>
Do you mean, like this?
$file = file_get_contents('/path/to/log', true);
// Separate by line
$lines = explode(PHP_EOL, $file);
foreach ($lines as $line) {
if (strpos($line, '/') === false) {
// If the line doesn't contain a "/", echo it
echo $line . PHP_EOL;
}
}
For anyone wondering, PHP_EOL is the PHP constant for "end of line" and promotes consistency between different systems (Windows, UNIX, etc.).
If you are iterating through the file line by line you can check with preg_match if the line contains /character and skip the echo if it does. If not, first split them at new line and iterate over that array.
If you don't want to split the file you can probably use preg_replace with a regexp such as (^|\n).*/.*(\n|$) and replace with empty string.
Use the str_replace function -
http://php.net/manual/en/function.str-replace.php. Alternate solution (before escaping the special characters) -
/* pattern /\/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\sconnected/ = /xx.xx.xx.xx connected */
/* pattern will be replaced with "newtext" */
$file = file_get_contents("/path/to/log", true);
$lines = explode("\n", $file);
foreach ($lines as $line)
$correctline = preg_replace( '/\/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\sconnected/', 'newtext', $line );
echo $correctline;
}
<?php
$file = file_get_contents("/path/to/log", true);
$lines = explode("\n", $file);
foreach ($lines AS $num => $line)
{
if ( strpos($line, "/") === false ) // Line doesn't contain "/"
{
echo htmlspecialchars($line) . "\n";
}
}
?>

Selecting an uncommented line from a text file

I have a text file full of proxy servers. Some are commented with a # at the beginning and should not be used. I have tried to do this using the code below, but it is still picking commented lines. Where am I going wrong?
function getProxy()
{
$file = file('proxy.txt',FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$line = $file[array_rand($file)];
if (strpos($line,'#') !== FALSE) { getProxy(); }
return $line;
}
Ideally I think the code should probably do some form of while loop until it picks a proxy (at random) which does not have a # at the beginning - rather than calling the function each time and reloading the file.
Help!
Actually, the best way to handle the problem is to remove any line that is commented, and only then pick a random result.
Otherwise you might have a very bad luck streak or a file with thousands of commented lines and one or two active, and will wait for hours to have the randomness pick the one line that is valid.
function getProxy()
{
$file = file('proxy.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($file as $key => $line) {
if (strpos(ltrim($line), "#") === 0) {
unset($file[$key]);
}
}
$line = $file[array_rand($file)];
return $line;
}
You can use array_filter() instead, like this:
$file = array_filter($file, function($value){return !(strpos(ltrim($value), "#") === 0);});
true - loop is better here:
function getProxy()
{
$file = file('proxy.txt',FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
do {
$line = $file[array_rand($file)];
} while(strpos($line,'#') !== FALSE);
return $line;
}
you must also add some additional condition - if file have only commented lines it will now create infinite loop, so better idea would be:
function getProxy()
{
$maxChecks=100;
$i=0;
$file = file('proxy.txt',FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
do {
$line = $file[array_rand($file)];
if($i++>$maxChecks) break;
} while(strpos($line,'#') !== FALSE);
if($i>$maxChecks)
return false;
return $line;
}

Any function to take an array of strings and return a CSV line?

I have an array of strings and want a way to create a CSV line from them. Something like:
$CSV_line = implode(',',$pieces);
Will not work as the pieces may contain comma and double quotes.
Is there a PHP built in function that takes the pieces and return a well formatted CSV line?
Thanks,
Roge
If you want to write that line to a file, you can use fputcsv
Using the streams functionnality of PHP, it should be possible to write to a variable -- indeed, there's one guy in the comments of str_getcsv who posted his implementation of str_putcsv :
<?php
function str_putcsv($input, $delimiter = ',', $enclosure = '"') {
// Open a memory "file" for read/write...
$fp = fopen('php://temp', 'r+');
// ... write the $input array to the "file" using fputcsv()...
fputcsv($fp, $input, $delimiter, $enclosure);
// ... rewind the "file" so we can read what we just wrote...
rewind($fp);
// ... read the entire line into a variable...
$data = fread($fp, 1048576); // [changed]
// ... close the "file"...
fclose($fp);
// ... and return the $data to the caller, with the trailing newline from fgets() removed.
return rtrim( $data, "\n" );
}
?>
Note : this code is not mine -- it's a copy-paste of the one posted by Ulf on php.net.
You could even write a Class to do this
class CSV_ARRAY {
static public function arr_to_csv_line($arr) {
$line = array();
foreach ($arr as $v) {
$line[] = is_array($v) ? self::arr_to_csv_line($v) : '"' . str_replace('"', '""', $v) . '"';
}
return implode(",", $line);
}
static public function arr_to_csv($arr) {
$lines = array();
foreach ($arr as $v) {
$lines[] = self::arr_to_csv_line($v);
}
return implode("\n", $lines);
}
}
you could useit like this
$csvlines = CSV_ARRAY::arr_to_csv_line($myarray);
file_put_contents($csvlines,"mycsv.csv");
thats it ;-)
As far as I know there is no such built in function. The one I'm aware of is fputcsv that does exactly what you want
but it does not return the CSV line, but writes it to a file.
<?php
$pieces = array (
'a,b,c,d', // contains comma.
'"1","2"' // contains double quotes.
);
$fp = fopen('file.csv', 'w');
fputcsv($fp, $pieces); // "a,b,c,d","""1"",""2""" written
fclose($fp);
?>
Most of the times you want create the line of CSV and write it to the file. So the above function should suffice.
I'd written one such function for PHP4 as it does not support fputcsv. I'll share it with you:
// If a value contains a comma, a quote, a space, a tab, a newline, or a linefeed,
// then surround it with quotes and replace any quotes inside it with two quotes
function make_csv_line($values)
{
// iterate through the array ele by ele.
foreach($values as $key => $value)
{
// check for presence of special char.
if ( (strpos($value, ',') !== false) || (strpos($value, '"') !== false) ||
(strpos($value, ' ') !== false) || (strpos($value, "\t") !== false) ||
(strpos($value, "\n") !== false) || (strpos($value, "\r") !== false))
{
// if present, surround the ele in quotes..also replace
// already existing " with ""
$values[$key] = '"' . str_replace('"', '""', $value) . '"';
}
}
// now create the CSV line by joining with a comma, also put a \n at the end.
return implode(',', $values) . "\n";
}
Here is a simpler fputcsv implementation:
$stdout = fopen('php://output','w'); // 'stdout' is for CLI, 'output' is for Browser
fputcsv($stdout, array('val,ue1','val"ue2','value3','etc'));
fflush($stdout); // flush for fun :)
fclose($stdout);
I snarfed this elswhere on SO and posted here for faster reference, please bump/credit the original posting:
Is my array to csv function correct?
Well, the thing is, there is no well formatted CSV. For instance, Open Office uses the semicolon (;) as default delimiter, while Excel expects it to be a comma (,). But fact is, no standard exists.
Assuming the Array looks something like this:
Array
0 => Some string
1 => Some other string, with comma
2 => And a third one with "double quotes"
);
You could either use implode with a different delimiter, e.g.
$delimiter = chr(9); // Tab
$delimiter = ';' // Semicolon. Excel's default
$delimiter = '|' // Pipe
$delimiter = "','"; // Comma plus Single Quote
If that is not working, run the String array through array_filter first and change the double quotes and comma via callback to whatever you think they should be, before exploding with just a comma delimiter:
$csv = implode(',' array_filter($array, 'my_csv_prepare'));
But keep in mind, this does not guarantee your consuming application to be able to read the CSV. It really depends on how they implemented CSV parsing. Like I said: no standard.

Categories