I've got a large flat file of usernames and emails in the following format:
"username", "email"
"username", "email"
"username", "email"
etc...
I need to take the email and search for the username, but for some reason it will not return a result. It works if I search opposite.
$string = "user_email#something.com";
$filename = "user_email.txt";
$h = fopen("$filename","r");
$flag=0;
while (!feof ($h)) {
$buffer = fgets($h);
$thisarray = split(",", $buffer);
if ($string == str_replace('"','', $thisarray[1])) {
$i = 1;
$i++;
echo '<td bgcolor="#CCFFCC"><b style="color: maroon">' . str_replace('"','',$thisarray[0]). '</b></td>';
}
Any ideas? Thanks!
As per reko_t's suggestion: Use fgetcsv to read individual lines of csv into arrays, until you find one where the second element matches your search term. The first element then is the username. Something like:
<?php
function find_user($filename, $email) {
$f = fopen($filename, "r");
$result = false;
while ($row = fgetcsv($f)) {
if ($row[1] == $email) {
$result = $row[0];
break;
}
}
fclose($f);
return $result;
}
You may use fgetcsv() directly
$string = "user_email#something.com";
$filename = "user_email.txt";
$h = fopen("$filename","r");
$flag=0;
while (!feof ($h)) {
list($username, $email= fgetcsv($h);
if ($string == $email) { /* do something */ }
}
fgetcsv() (as a nice side effect) also removes the "field enclosures" (the double quotes ") for you, if they exists.
Your own example probably does not work, because if you have such a line
"username", "email"
splitting at , will result in
'"username"'
' "email"'
Notice the whitespace before "email", that you forgot to remove. Additional using str_replace() to remove the surrounding quotes is quite unsafe. Have a look at trim().
First, just use file() to get the contents of the file into an array:
$file_contents = file( $filename, 'r' );
Now loop through the contents of the array, splitting the strings and examining the email address:
foreach ( $file_contents as $line ) {
list ( $username, $email ) = str_split( ',' $line );
if ( trim( $email ) == $string ) {
// A match was found. Take appropriate action.
}
}
I think the easiest solution is to use file() with str_getcsv().
The code would be something like this:
foreach (file($fileName, FILE_SKIP_EMPTY_LINES) as $line) {
$columns = str_getcsv($line); // Where $columns[0] and $columns[1] hold the username and email respectively.
}
I truly believe that all examples in other answers works!
But all they are slow, because all of them travers each line in csv file...
I have another example how to find desired string:
$command = sprintf("grep '%s,%s' -Er %s", $userName, $email, $file);
$result = `$command`;
Yes it some kind of dark matter, but it really works and it really fast!
While fgetcsv is potentially a more elegant solution, that doesn't answer your original question: your second array element has a newline, and you're comparing against a string that doesn't.
To fix:
if ($string == str_replace('"','', chop($thisarray[1]))) {
Related
I want to do if conditional between text data and variable data then delete the line
Example
I have a txt data with usernames like ( one two one three one) every user in line,
And i want to delete all data except "one" username
My Code;
if(file_get_contents('visitors.txt') != "one") {
$GetLine = ;
function removeLine ($url, $lineToRemove)
{
$data = file_get_contents($url);
$lines = explode(PHP_EOL, $data);
$lineNo = 1;
foreach($lines as $line)
{
$linesArray[$lineNo] = $line;
$lineNo++;
}
unset($linesArray[$lineToRemove]);
return implode("\n", $linesArray);
}
$data = removeLine ("username.txt", $getLine);
echo $data
}
the function is used to remove lines.
My problem is doing if with the data + $getLine number, I just want to remove all the lines except line that has one word.
Can simply do it with a regular expression:
$file = preg_grep('#one#', file('file.txt'));
This will make $file an array holding only lines containing the string "one". To turn the array back into a string, you just implode it.
If you only want to echo the lines containing "one", you can also use iterators:
$file = new RegexIterator(new SplFileObject("file.txt"), '#one#');
foreach ($file as $content) {
echo $content, PHP_EOL;
}
This will go over the file line by line and echo any line having the string one in it. The benefit is that it doesn't use two arrays as intermediate structures.
Just a note, you shouldn't be defining functions inside an if statement.
Also, unless I'm misunderstanding, you shouldn't even need line numbers.
function remove_line( $data, $remove ){
$lines = explode( PHP_EOL, $data ); // Convert to Array
$new_lines = ''; // Start a new variable we'll add to in a loop
foreach( $lines as $line ){
$line = trim( $line ); // Trim Whitespace
if( $line != $remove ){
// Line isn't a line we want removed, so save it plus an EOL
$new_lines .= $line.PHP_EOL;
}
}
return $new_lines;
}
Now if you load in a file like so: $file = file_get_contents( 'my-file.txt' ); that contains the following:
One
Two
One
Three
One
Once you run it through the remove_line function, you'll end up something like:
$file = file_get_contents( 'my-file.txt' );
$new_file = remove_line( $file, 'One' );
var_dump( $new_file ); // Returns: string(10) "Two Three "
I'm getting used to PHP and trying to remove a line from a file (if it exists) and resave the file.
So if I had the file
user1
user2
user3
user4
I could use
if(existsAndRemove("user3")){
do thing
}
I've tried using code similar to the code below but it sometimes bugs out and will only remove a line if it is last in the file. I have no idea how to fix this.
$data2 = file("./ats.txt");
$out2 = array();
foreach($data2 as $line2) {
if(trim($line2) != $acc) {
$out2[] = $line2;
}
}
$fp2 = fopen("./ats.txt", "w+");
flock($fp2, LOCK_EX);
foreach($out2 as $line2) {
fwrite($fp2, $line2);
}
flock($fp2, LOCK_UN);
fclose($fp2);
}
}
Any help at all would be greatly appreciated, and i would also appreciate if you could explain the code too so I could easier learn from it!!
Thank you.
If the file size is small enough that you're not worried about reading it all into memory, you could do something more functional
// Read entire file in as array of strings
$data = file("./ats.txt");
// Some text we want to remove
$acc = 'user3';
// Filter out any lines that match $acc,
// ignoring any leading or trailing whitespace
//
$filtered_data = array_filter(
$data,
function ($line) use ($acc) {
return trim($line) !== $acc;
}
)
// If something changed, write the file back out
if ($filtered_data !== $data) {
file_put_contents('./ats.txt', implode('', $filtered_data));
}
Something like this might work:
function remove_user($user) {
$file_path = "foo.txt"
$users = preg_split("[\n\r]+", file_get_contents($file_path));
foreach ($users as $i => $existing) {
if ($user == $existing) {
$users = array_splice($users, $i, 1);
file_put_contents($file_path, implode("\n", $users));
break;
}
}
}
Should be much easier since you're already using file():
$data2 = file("./ats.txt", FILE_IGNORE_NEW_LINES);
unset($data2[array_search('user3', $data2)]);
file_put_contents("./ats.txt", implode("\n", $data2));
Or to check if it exists first:
$data2 = file("./ats.txt", FILE_IGNORE_NEW_LINES);
if( ($key = array_search('user3', $data2)) !== false ) {
unset($data2[$key]);
file_put_contents("./ats.txt", implode("\n", $data2));
}
I have a SQL file which i created from another database (named as test) on my localhost and now i want to insert this data into another database ( named as server_db) via PHP Script .
I tried and my PHP Script is working fine and creating the tables into server_db database.
But values in those tables are not inserting ..... Please Help
My PHP Code is given below
<?php
class Executer {
public $path="";
public function execute($path){
// MySql connectivity
$link = mysql_connect("localhost","root","");
mysql_select_db("server_db");
//file content
$content = file_get_contents($path);
//remove the comments
$lines = explode("\n",$content);
$content = '';
foreach($lines as $line){
$line = trim($line);
if( $line && !$this->startsWith($line,'--') ){
$content .= $line . "\n";
}
}
//convert data into array of queries
$content = explode(";", $content);
//run the query
$total = $sucess=0;
foreach($content as $command){
if(trim($command)){
$success = (mysql_query($command)==false ? 0 : 1);
}
}
}
public function startsWith($string, $sym_com){
$length = strlen($sym_com);
return (substr($string, 0, $length) === $sym_com);
}
} $path = "C:/xampp/htdocs/final/downloads/server_database_file.sql";
execute($path);
I think you need to check your SQL text file encoding. because the line delimiter for each encoding is not always "\n". You can try change with "\r"
If you on localhost you can use exec function with mysqldump
exec('mysqldump server_database > C:/xampp/htdocs/final/downloads/server_database_file.sql')
Try this. Just wrote it up, realizing I didn't have a function for this. You need to verify that ; is the last character of a line, exploding by ; can lead to false mid-data splits. Below approach simply buffers the lines up until it finds a terminating ;, then inserts them into an array and resets the buffer.
function parse_sql_file($filepath) {
$queries = [];
$sql_query = [];
$lines = file($filepath);
foreach($lines as $line) {
$line = trim($line);
// This is a comment: move on, nothing to see here.
if (substr($line, 0, 2) == '--') continue;
$sql_query[] = $line;
// We found a terminator: do the needful.
if (substr($line, -1) == ';') {
$queries[] = trim( implode("\n", $sql_query) );
$sql_query = [];
}
}
return $queries;
}
$queries = parse_sql_file('my.sql');
var_dump($queries);
I have this script that extracts a .csv file from the database that holds data for different locals that a user has logged into. The .csv files come like this:
"id_user";"id_local"
"1";""
"2";"2,3,4"
"3";""
"5";"2,5"
"10";""
"13";"2"
"14";"5"
"15";"2"
"16";"1"
"20";"2"
"21";""
As you can se, it get one register per user
But, to manipulate it properly, we need it like this:
"id_user";"id_local"
"2";"2"
"2";"3
"2";"4"
"5";"2"
"5";"5"
"13";"2"
"14";"5"
"15";"2"
"16";"1"
"20";"2"
So, I need to create a function that deletes users with no local and splits different locals of the same user in different registers. Does anyone knows how can I do it?
Here is the code I have so far but I'm not sure if I'm on the right way:
function fix_local_secundario(){
$filename = "local_secundario.csv";
$file_locais = file_get_contents($filename);
$locais = explode("\n", $file_locais);
// $pattern = "/,/";
// $replacement = "\"\n;\"";
while ($line = current($locais)) {
$line = str_getcsv($line, ';', '"','\n');
// $line = preg_replace($pattern, $replacement, $line);
var_dump($line);
echo "\n";
next($locais);
}
}
Try this and see if this works:
function fix_local_secundario(){
$filename = "local_secundario.csv";
$file_locais = file_get_contents($filename);
$locais = explode("\n", $file_locais);
while ($line = current($locais)) {
// do first split on ; character
$arr1 = explode(";", $line);
// if the part after ; is not empty for this line
if ($arr1[1]!='""'){
// split it further on , character
$arr2 = explode(",", $arr1[1]);
foreach ($arr2 as $key => $val){
if($val[0] != '"'){
$val = '"'.$val;
}
if($val[strlen($val)-1] != '"'){
$val = $val . '"';
}
echo $arr1[0] . ";" . $val . "<BR>";
}
}
next($locais);
}
}
Once this basic piece is working, you should change it to return values rather than echo values since this code is part of a function as per updates made to your question.
What about this…
$f = fopen("myfile.csv", "r");
while($row = fgetcsv($f, 0, ";")){
$locals = explode(",", $row[1]);
if (count($locals)>1){
foreach($locals as $local)
// iterate with $row[0] and $local
}elseif($row[1] != "")
// use $row[0] and $row[1]
}
Let say i want to read a text file using php.
Now my text file contain
User=Test
Age=18
Gender=F
User=Test2
Age=34
Gender=M
and following like that.
Now let say i want to use php to read the text file and find only value of User= and display it.
What is the easiest way to accomplish this?
Thank you.
This may be more than you're looking for, but if you're looking to parse a text file
and you're not tied to a specificformat you should use one that php has inbuilt support for. To me the two most obvious options are XML and JSON. IMHO JSON is probably easiest.
In your example the data file might look like this
[
{
'User':'Test',
'Age':18,
'Gender':'F'
},
{
'User':'Test2',
'Age':34,
'Gender':'M'
}
]
The php to read from it would be
contents = file_get_contents($filename);
$contents = utf8_encode($contents);
$m = json_decode($contents);
Now you can work on $m as you would any array
foreach( $m as $user )
{
print $user->User . "\n";
}
$filename = "users.txt";
$user_file_array = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
//Now you have an array of each line of the file.
foreach($user_file_array as $user_info) {
if(strpos($user_info, "User=") !== false) {
$users[] = str_replace("User=", "", $user_info);
}
}
The above assumes that each bit of info is on a new line, that User= is case-sensitive, and that you are okay with looping through whole file. You will get an array returned of just the user names on the right-side of the User=.
If you want that to be echoed out in a column, either change the bit where the $users array gets built, or add this to the end:
echo implode("\n" $users);
Unless you're looking for a specific value, you're basically going to have to read the whole file in to memory. You could read it line-by-line and output any line that started with "User", like this:
$fp = fopen("test_input.txt","r");
while(! feof($fp)) {
$line = fgets($fp);
if (substr($line,0,5) == "User=") echo substr($line,5);
}
fclose($fp);
If you wanted the information in a more useful form, you could break it up into an array of users. Assuming that each "section" of your file is separated by a double newline, you could do this:
$out = array();
$contents = file_get_contents('test_input.txt');
$blocks = explode("\n\n",$contents);
foreach($blocks as $b)
{
$user = array();
$lines = explode("\n",$b);
foreach($lines as $line) {
list($key,$value) = explode("=",$line,2);
$user[$key] = $value;
}
$out[] = $user;
}
//now have an array of user info
foreach($out as $i) echo $i['User'];
Obviously this makes assumptions about your data (such as all lines separated by "\n" characters), but you get the idea.
You could try fgets() to get a line of the file and substring the beginning to test if it starts with the proper text. There may be easier ways.
<?php
$lines = array();
$file = fopen("sample.txt", "r") or exit("Unable to open file!");
//Output a line of the file until the end is reached
$i = 0;
while(!feof($file))
{
$i++;
$lines[$i] = fgets($file). "<br />";
}
fclose($file);
$matches = preg_grep("/^User=(.*)/", $lines);
print_r($matches);
?>
Taken from http://php.net/manual/en/function.preg-grep.php, http://www.phpfreaks.com/forums/index.php?topic=213127.0
If you're married to/stuck with the format that you described, then you can try out my code below. It will give you a nice array that you can work with easily. Otherwise, I suggest you take Michael Anderson's advice and switch over to JSON as it will save you time and normalize things a bit.
$rawData = file_get_contents("data.txt");
$users = array();
$tmpUser = array();
foreach ( file("data.txt", FILE_IGNORE_NEW_LINES) as $line ) {
// Blank line denotes the end of a record
if ( empty($line) ) {
$users[] = $tmpUser;
$tmpUser = array();
continue;
}
list($key, $value) = explode("=", $line, 2);
$tmpUser[ strtolower(trim($key)) ] = trim($value);
}
// Add last record
if ( !empty($tmpUser) ) {
$users[] = $tmpUser;
}
print_r($users);
Result
Array
(
[0] => Array
(
[user] => Test
[age] => 18
[gender] => F
)
[1] => Array
(
[user] => Test2
[age] => 34
[gender] => M
)
)
I realize that you asked specifically to be able to get just the user name; however, this is probably more beneficial in the term of whatever you are trying to accomplish.
chk this code
<?php
$file = "test.txt";
$userArr=array();
$f = fopen($file, "r");
while ( $line = fgets($f) )
{
$lineArr = explode('=',$line);
if($lineArr[0]=='User')
{
echo "User Name: ".$lineArr[1];
echo "<br/>";
$userArr[] = $lineArr[1];
}
}
print_r($userArr);
?>
For more info chk this here