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]
}
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 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've got a textfile where I want to catch every first word from:
First name|All|01.01.55.41
Second name||01.01.55.41
Third name||01.01.55.41
Which I'm trying with:
function get_content() {
$mailGeteld = NULL;
$mailGeteld = file_get_contents("content.txt");
$mailGeteld = explode("|",$mailGeteld);
return $mailGeteld[0];
}
But now I'm only getting "First name", how can I loop it so the result is like:
First name, Second name, Third name
file read's a file line by line.
function get_content() {
$firstWords = array();
$file = file("content.txt"); //read file line by line
foreach ($file as $val) {
if (trim($val) != '') { //ignore empty lines
$expl = explode("|", $val);
$firstWords[] = $expl[0]; //add first word to the stack/array
}
}
return $firstWords; //return the stack of words - thx furas ;D
}
echo implode(', ', get_content()); //puts a comma and a blankspace between each collected word
You can use SplFileObject
$file = new SplFileObject("log.txt", "r");
$data = array();
while(! $file->eof()) {
$data[] = array_shift(($file->fgetcsv("|")));
}
echo implode(", ", $data);
Your function operates on a single row. I propose you move file_get_contents("content.txt"); out of function and iterate for each row and use your function each time.
I want to record downloads in a text file
Someone comes to my site and downloads something, it will add a new row to the text file if it hasn't already or increment the current one.
I have tried
$filename = 'a.txt';
$lines = file($filename);
$linea = array();
foreach ($lines as $line)
{
$linea[] = explode("|",$line);
}
$linea[0][1] ++;
$a = $linea[0][0] . "|" . $linea[0][1];
file_put_contents($filename, $a);
but it always increments it by more than 1
The text file format is
name|download_count
You're doing your incrementing outside of the for loop, and only accessing the [0]th element so nothing is changing anywhere else.
This should probably look something like:
$filename = 'a.txt';
$lines = file($filename);
// $k = key, $v = value
foreach ($lines as $k=>$v) {
$exploded = explode("|", $v);
// Does this match the site name you're trying to increment?
if ($exploded[0] == "some_name_up_to_you") {
$exploded[1]++;
// To make changes to the source array,
// it must be referenced using the key.
// (If you just change $v, the source won't be updated.)
$lines[$k] = implode("|", $exploded);
}
}
// Write.
file_put_contents($filename, $lines);
You should probably be using a database for this, though. Check out PDO and MYSQL and you'll be on your way to awesomeness.
EDIT
To do what you mentioned in your comments, you can set a boolean flag, and trigger it as you walk through the array. This may warrant a break, too, if you're only looking for one thing:
...
$found = false;
foreach ($lines as $k=>$v) {
$exploded = explode("|", $v);
if ($exploded[0] == "some_name_up_to_you") {
$found = true;
$exploded[1]++;
$lines[$k] = implode("|", $exploded);
break; // ???
}
}
if (!$found) {
$lines[] = "THE_NEW_SITE|1";
}
...
one hand you are using a foreach loop, another hand you are write only the first line into your file after storing it in $a... it's making me confuse what do you have in your .txt file...
Try this below code... hope it will solve your problem...
$filename = 'a.txt';
// get file contents and split it...
$data = explode('|',file_get_contents($filename));
// increment the counting number...
$data[1]++;
// join the contents...
$data = implode('|',$data);
file_put_contents($filename, $data);
Instead of creating your own structure inside a text file, why not just use PHP arrays to keep track? You should also apply proper locking to prevent race conditions:
function recordDownload($download, $counter = 'default')
{
// open lock file and acquire exclusive lock
if (false === ($f = fopen("$counter.lock", "c"))) {
return;
}
flock($f, LOCK_EX);
// read counter data
if (file_exists("$counter.stats")) {
$stats = include "$counter.stats";
} else {
$stats = array();
}
if (isset($stats[$download])) {
$stats[$download]++;
} else {
$stats[$download] = 1;
}
// write back counter data
file_put_contents('counter.txt', '<?php return ' . var_export($stats, true) . '?>');
// release exclusive lock
fclose($f);
}
recordDownload('product1'); // will save in default.stats
recordDownload('product2', 'special'); // will save in special.stats
personally i suggest using a json blob as the content of the text file. then you can read the file into php, decode it (json_decode), manipulate the data, then resave it.
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]))) {