How to rewrite specific values of a file through PHP? - php

<?php
$info = "Hi";
$file = fopen("file.txt","w");
fwrite($file,$info);
fclose($file);
?>
I am currently using the code above to write a value into a text file. However, is it possible to retrieve certain variables that are stored within that text file and just rewrite them instead?
Example:
file.txt
$one = "first";
$two = "second";
$three = "third";
Through PHP code, a specified "variable" in the text file should have its contents changed.
New file.txt
$one = "first";
$two = "hi";
$three = "third";

yes, you can use str_replace() to replace the variables with the data you like
$s_input = 'this is a #first text';
$a_repfr = array('#first', '#second', '#third');
$a_repto = array('funny', 'php', 'love');
$s_output = str_replace($a_repfr, $a_repto, $s_input);

If I understand you correctly, you have some PHP code written in a file, file.txt. If you have only stored variables, I believe you can get away with some regular expression to do what you want.
Nevertheless, for anything more complex (maybe even for this specific case), I would recommend that you use some PHP parser to parse all the variables and their values, and make your changes accordingly. (here's a PHP parser written in PHP).
EDIT:
Just to clear things up, a simple replacement will not suffice. Imagine you have something like $first = "a";, and then you decide to replace a, with \. A naive replacement, would leave you with $first = "\"; in your file.txt file.

Related

string is not getting printed and showing error of division by zero

string $unencodedData; is not getting printed and showing error of division by zero
$date = date_create();
$timestamp= date_timestamp_get($date);
$rand = mt_rand(100000,999999);
$string = "cp-string";
$unencodedData = "cp-string"/'.$timestamp.'/'.$rand.';
echo $unencodedData;
file_put_contents('./public/image/share/image.png',file_get_contents('$unencodedData'));
dont know where code is wrong.. hinking may be wrong in declaring $unencodedData;
It a simple case of miss-matched quote pairs what I think you wanted is :
$unencodedData = 'cp-string/'.$timestamp.'/'.$rand;
Also please note that if you don't care about a little overhead you can also use the following to make your code a little more readable :
$unencodedData = "cp-string/$timestamp/$rand";
You may try to declare $unencodeData like so
$unencodeData = 'cp-string/'.$timestamp.'/'.$rand;
Or if you are trying to use the $string var it would be
$unencodeData = $string.'/'.$timestamp.'/'.$rand;
Looks like you are trying to divide strings.. is unencodedData supposed to be a file? If so, try:
$unencodedData = $string . '/' . $timestamp . '/' . $rand";
or
$unencodedData = "{$string}/{$timestamp}/{$rand}";
You have to distinguish between "..." and '...'.
'...' means just a basic string, some text. There can't be something special about it. No variables, no linebreak-signs (\n),etc.
"..." means php has to have a close look at it. Inside ".." there might be variables like "My name is $name." which php replaces with the content of said variable.
If you use " inside a ' or vice versa, it becomes an ordinary string.
You can do something like "I don't know".
If you use " inside "..." you have to escape it. like so "and then he said \"I don't know $name\"". Same goes for '...'.
So what you can do is either:
$unencodedData = "cp-string/$timestamp/$rand.";
or
$unencodedData = 'cp-string/'.$timestamp.'/'.$rand.'.';
(just for educational purposes: you could even do something like:
$unencodedData = 'cp-string/'.$timestamp."/$rand.";)
If you don't need to parse any variables or \n inside your string, just stick to ''. It's a little faster parseable for the php interpreter.
Not a 100% sure what your goal is here, but this looks like what I think you are trying to achieve:
// -- setup ----------------
$path = './public/image/share/image.png';
$randMin = 100000;
$randMax = 999999
// -- build that string ----
$timestamp= date_timestamp_get(date_create());
$rand = mt_rand($randMin,$randMax);
$unencodedData = "cp-string/$timestamp/$rand.";
// prints something like: cp-string/19245436/123456.
// -- print and save --------
echo $unencodedData;
file_put_contents($path,file_get_contents($unencodedData));

Counting Variables using PHP

Building a simple jQuery/PHP setup where for example the PHP will store 5 variables each containing a simple string. These variables are all separate and not in an array. The jQuery used is just a simple fadeIn/fadeOut function which fades out the 1st string and fades in the 2nd string. Got all that working.
However this is for a client who doesn't really even know what a variable is and has asked that the 5 strings be "changable" so I'm creating a seperate PHP file that contains the strings so that the client can just open that file and change the strings within there and possibly add/delete strings from the file.
What I want the php to do is "count" how many variables there are then echo each string depending on how many variables there are. Variables are named like so
$text_0 = "Its a sentence";
$text_1 = "Its another sentence";
$text_2 = "Its a final sentence";
so obviously need a for statement
for(i=0;i<WHATGOESHERE?;i++){
echo $text_[i];
}
Thanks for any help.
If you want it to be editable for a non techguy, then dont even use the variables as its to easy to forget a ; or a $ or whatever. Just create a plain text file and in PHP use it as an array.
An added bonus is that the none tech guy is not able to inject PHP code to your system.
file.txt:
Its a sentence
Its another sentence
Its a final sentence
show.php:
<?php
$lines = file('file.txt');
//below is just an example, obviously it should be your jquery code
foreach ($lines as $line_num => $line) {
echo "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
}
//length would be count($lines) and upper bound count($lines)-1
?>
Give this to your non-techie:
Its a sentence
Its another sentence
Its a final sentence
Convert it into an array with:
$sentences = file('sentences.txt', FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
Done.
<?php
$text_0 = 'a';
$text_1 = 'b';
$text_2 = 'c';
$vars = preg_grep('#^text_\d+$#', array_keys(get_defined_vars()));
var_dump($vars);
?>
It's better to create array $text..

parsing inline variables from string from file in php

I'm localizing a website that I've built. I'm doing this by having a .lang file read and each line (syntax: key=string) is placed in a variable depending on the chosen language.
This array is then used to place the strings in the correct places.
The problem I'm having is that certain strings need to have hyperlinks in the middle of them for example someplace I've put my name that links to my contact page. Or a lot of the readouts of the website need to be in the strings.
To solve this I've defined a variable that holds the html + Forecaster + html,
and the localization file contains the $Forecaster variable in the string.
The problem with this as I promptly discovered is that it stubbornly refuses to parse the inline variables in the strings from the file.
Instead it prints the string and variable name as it looks in the file.
And I have yet to find a way to make it parse the variables.
For example "Heating up took $str_time" would be printed on the page exactly like that, instead of inputting the previously defined value of $str_time.
I currently use fopen() and fgets() to open and read the lines. I then explode them to separate the key and the string and then place these into the array.
Is there a way to make it parse the variables, or alternatively is there another way of reading the lines that allows for parsing the inline variables?
The code that gets the line and converts it to the array looks like this:
(It obviously loops through the lines)
#list($key, $string) = explode('=', $line);
$key = strtok($line, '=');
$string = strtok('=');
$local[$key] = $string;
$counter++;
echo $local[$key] . "<br>";
The counter is unused and the echo is for testing.
A line from the .lang file looks like this:
fuel.results.heatup.timeused=Heating up took $str_time
I would call the array where I want the string like this:
$local['fuel.results.heatup.timeused']
As you can see I've tried both explode and strtok but it hasn't made a difference.
Personally I'd write your text file in JSON format to make it easier to pull data out.
Here is a solution directly from the php manual: http://nz2.php.net/manual/en/function.eval.php
$string = 'cup';
$name = 'coffee';
$str = 'This is a $string with my $name in it.';
echo $str. "\n";
eval("\$str = \"$str\";");
echo $str. "\n";
It is worth noting that eval() can be very dangerous used in the wrong way so make sure you're code is very secure E.g. if someone altered your txt file with real PHP code they could execute it directly on the server.
Another approach would require you to know all your variable names and could then do something like:
$str = 'Heating up took $str_time';
echo 'str=' . str_replace('$str_time', $str_time, $str);
Or do this via an array:
$str = 'Heating up took $str_time as well as $other_value';
$vars = Array('str_time', 'other_value');
foreach($vars as $varName) {
$str = str_replace('$' . $varName, $$varName, $str);
}
echo 'str=' . $str;
If you not know all the variable name, you can use this example, without eval(). It is indicatred to avoid eval().
$str = 'fuel.results.heatup.timeused=Heating up took $str_time';
$str_time = 'value';
if(preg_match('/\$([a-z0-9_]+)/i', $str, $v)) {
$vname = $v[1];
$str = str_replace('$'.$vname, $$vname, $str);
}
echo $str; // fuel.results.heatup.timeused=Heating up took value

Parse variables within string

I'm storing some strings within a *.properties file. An example of a string is:
sendingFrom=Sending emails from {$oEmails->agentName}, to {$oEmails->customerCount} people.
My function takes the value from sendingFrom and then outputs that string on the page, however it doesn't automatically parse the {$oEmails->agentName} within. Is there a way, without manually parsing that, for me to get PHP to convert the variable from a string, into what it should be?
If you can modify your *.properties, here is a simple solution:
# in file.properties
sendingFrom = Sending emails from %s, to %s people.
And then replacing %s with the correct values, using sprintf:
// Get the sendingFrom value from file.properties to $sending_from, and:
$full_string = sprintf($sending_from, $oEmails->agentName, $oEmails->customerCount);
It allows you to separate the logic of your app (the variables, and how you get them) from your presentation (the actual string scheme, stored in file.properties).
Just an alternative.
$oEmails = new Emails('Me',4);
$str = 'sendingFrom=Sending emails from {$oEmails->agentName}, to {$oEmails->customerCount} people.';
// --------------
$arr = preg_split('~(\{.+?\})~',$str,-1,PREG_SPLIT_DELIM_CAPTURE);
for ($i = 1; $i < count($arr); $i+=2) {
$arr[$i] = eval('return '.substr($arr[$i],1,-1).';');
}
$str = implode('',$arr);
echo $str;
// sendingFrom=Sending emails from Me, to 4 people.
as others mentioned eval wouldn't be appropriate, I suggest a preg_replace or a preg_replace_callback if you need more flexibility.
preg_replace_callback('/\$(.+)/', function($m) {
// initialise the data variable from your object
return $data[$m[1]];
}, $subject);
Check this link out as well, it suggests the use of strstr How replace variable in string with value in php?
You can use Eval with all the usual security caviats
Something like.
$string = getStringFromFile('sendingFrom');
$FilledIn = eval($string);

php simplest case regex replacement, but backtraces not working

Hacking up what I thought was the second simplest type of regex (extract a matching string from some strings, and use it) in php, but regex grouping seems to be tripping me up.
Objective
take a ls of files, output the commands to format/copy the files to have the correct naming format.
Resize copies of the files to create thumbnails. (not even dealing with that step yet)
Failure
My code fails at the regex step, because although I just want to filter out everything except a single regex group, when I get the results, it's always returning the group that I want -and- the group before it, even though I in no way requested the first backtrace group.
Here is a fully functioning, runnable version of the code on the online ide:
http://ideone.com/2RiqN
And here is the code (with a cut down initial dataset, although I don't expect that to matter at all):
<?php
// Long list of image names.
$file_data = <<<HEREDOC
07184_A.jpg
Adrian-Chelsea-C08752_A.jpg
Air-Adams-Cap-Toe-Oxford-C09167_A.jpg
Air-Adams-Split-Toe-Oxford-C09161_A.jpg
Air-Adams-Venetian-C09165_A.jpg
Air-Aiden-Casual-Camp-Moc-C09347_A.jpg
C05820_A.jpg
C06588_A.jpg
Air-Aiden-Classic-Bit-C09007_A.jpg
Work-Moc-Toe-Boot-C09095_A.jpg
HEREDOC;
if($file_data){
$files = preg_split("/[\s,]+/", $file_data);
// Split up the files based on the newlines.
}
$rename_candidates = array();
$i = 0;
foreach($files as $file){
$string = $file;
$pattern = '#(\w)(\d+)_A\.jpg$#i';
// Use the second regex group for the results.
$replacement = '$2';
// This should return only group 2 (any number of digits), but instead group 1 is somehow always in there.
$new_file_part = preg_replace($pattern, $replacement, $string);
// Example good end result: <img src="images/ch/ch-07184fs.jpg" width="350" border="0">
// Save the rename results for further processing later.
$rename_candidates[$i]=array('file'=>$file, 'new_file'=>$new_file_part);
// Rename the images into a standard format.
echo "cp ".$file." ./ch/ch-".$new_file_part."fs.jpg;";
// Echo out some commands for later.
echo "<br>";
$i++;
if($i>10){break;} // Just deal with the first 10 for now.
}
?>
Intended result for the regex: 788750
Intended result for the code output (multiple lines of): cp air-something-something-C485850_A.jpg ./ch/ch-485850.jpg;
What's wrong with my regex? Suggestions for simpler matching code would be appreciated as well.
Just a guess:
$pattern = '#^.*?(\w)(\d+)_A\.jpg$#i';
This includes the whole filename in the match. Otherwise preg_replace() will really only substitute the end of each string - it only applies the $replacement expression on the part that was actually matched.
Scan Dir and Expode
You know what? A simpler way to do it in php is to use scandir and explode combo
$dir = scandir('/path/to/directory');
foreach($dir as $file)
{
$ext = pathinfo($file,PATHINFO_EXTENSION);
if($ext!='jpg') continue;
$a = explode('-',$file); //grab the end of the string after the -
$newfilename = end($a); //if there is no dash just take the whole string
$newlocation = './ch/ch-'.str_replace(array('C','_A'),'', basename($newfilename,'.jpg')).'fs.jpg';
echo "#copy($file, $newlocation)\n";
}
#and you are done :)
explode: basically a filename like blah-2.jpg is turned into a an array('blah','2.jpg); and then taking the end() of that gets the last element. It's the same almost as array_pop();
Working Example
Here's my ideaone code http://ideone.com/gLSxA

Categories