$embedCode = <<<EOF
getApplicationContent('video','player',array('id' => $iFileId, 'user' => $this->iViewer, 'password' => clear_xss($_COOKIE['memberPassword'])),true)
EOF;
$name = str_replace($embedCode,"test",$content);
I'm trying to replace a section of code with another piece of code. I can do it with smaller strings but once I added the larger strings to $embedCode, it throw an "unexpected T_ENCAPSED_AND_WHITESPACE" error
you should unescape the $ using \$
$embedCode = <<<EOF
getApplicationContent('video','player',array('id' => \$iFileId, 'user' => \$this->iViewer, 'password' => clear_xss(\$_COOKIE['memberPassword'])),true)
EOF;
IF your objective is to use the vars name, if you want to use the real value of the variables, then the problem is in $this->iViewer...
remove ' around the memberPassword near the $_COOKIE
anyway seems you're looking for language construction that not interprets variable inside - so then you have to use not HEREDOC syntax - but regular string definition limited with '
$sample = 'qwe $asd zxc';
or escape $ with \ as Marcx propose below
Related
I use a config.php file that returns an array. Before releasing the project, I usually manually change the 'apiKey' value that I use while developing in the file. I forget to perform this replacement sometimes, so I'm looking for a programmatical way to find this in a string version of the file:
'apiKey' => '1234567890'
and replace with this:
'apiKey' => 'YourAPIKeyHere'
The development apiKey value, spaces, tabs and formatting are inconsistent (Developer/IDE specific), so I guess there are wildcards for that?
Then I can just make the change in my deployment script.
Edit to show sample of config.php (which will be read into a string, edited, then re-written as a file).
<?php
return array(
// Comments with instruction exist throughout the file. They must remain.
'apiKey' => 'ecuhi3647325fdv23tjVncweuYtYTv532r3',
...
);
Edit: **There are instructional comments in the config.php file that must remain. So re-writing a modified array will lose the comments, and that is undesirable.
Save the config file's text in a variable called $content.
Then call:
$content = preg_replace("~'apiKey'\s*=>\s*'\K[^']+~", 'YourAPIKeyHere', $content, 1);
Then overwrite the file with the updated variable.
http://php.net/manual/en/function.preg-replace.php
\s* means match zero or more whitespace characters.
\K means restart the match from this point.
[^']+ means match one or more non-single-quote character.
Regex101 Demo
PHP Demo
I assume that you have a config file such as;
return [
'dbname' = 'project',
'username' = 'root',
'password' = '123456',
.
.
.
'apiKey' => '1234567890',
]
So you can make a small helper method then you can use it before relasing your project..
function reset_config()
{
$file_path = "your/config/path";
$configs = require_once($file_path);
array_walk_recursive($configs, function (&$config, $key) {
$config = "your " . $key;
});
$string = var_export($configs,true);
$new_config_file = <<<HEAD
<?php
return $string;
HEAD;
file_put_contents($file_path, $new_config_file);
}
so all you need to use reset_config() function before relasing the project
You can use this simple RegEx to match any line containing a key between the apostrophes:
'apiKey' => '[^']+'
The [^']+ will find one or more characters between single quotes.
Just replace with your new line.
Edit:
Your replacement string would simply be:
'apiKey' => 'EnterYourAPIKeyHere'
I solved the issue by reading the file into an array and replacing the line with 'apiKey':
$array = file('app/config.php');
$string = "";
for($i = 0, $maxi = count($array); $i < $maxi; $i++)
{
if(strpos($array[$i],'apiKey')>0){
$string.=" 'apiKey' => 'YourAppAPIKeyHere',\r\n\r\n";
}else{
$string.=$array[$i];
}
}
It may not be the most elegant solution but it works. Until someone doesn't format their code right. For this reason, I would still like to use a RegEx that isolates the replacement to the required pattern. But RegEx is something I just don't get into, and there's other issues to resolve now.
Inspired by everyone who helped.
Feedback appreciated.
As i suggested you can use the PHP tokenizer extension functions to achieve your purpose
function replaceApiKey($configpath,$newKey='test',$newpath=''){
if(file_exists($configpath)&&is_readable($configpath)&&is_file($configpath))
$string = file_get_contents($configpath);
else
return false;
$tokens=token_get_all($string);
$start=false;
foreach($tokens as $key=>$token){
if(is_array($token)&&stripos($token[1],'apiKey')){
$start=true;
$tokens[$key]=$token[1];
continue;
}
if($start&&$token&&is_array($token)&&token_name($token[0])!=="T_COMMENT"&&token_name($token[0])!=="T_DOUBLE_ARROW"&&!ctype_space($token[1])){
$token[1]=$token[1][0].$newKey.$token[1][strlen($token[1])-1];
$start=false;
}
if(is_array($token)) $tokens[$key]=$token[1];
}
if(empty($newpath))
$newpath=$configpath;
if (file_put_contents($newpath, join('',$tokens)))
return true;
else
return false;}
This function take in parameter the config path,tokenize the content then search and replace the old apiKey by the new one and save the changes in the new path...
we have a PHP script that exports orders to .csv files. The system we are exporting too requires each field to be encapsulated in quote marks.
Here is the code where we set each field.
$order_data = array(
'type' => "H",
'order_type' => 'HOME',
'order_date' => $order->order_date,
'account_code' => "REAL",
'document_reference' =>'',
'reference1'=>'',
'reference2'=>'',
'delivery_addess_code'=> '',
'billing_first_name' => $order->billing_first_name ." ".$order->billing_last_name,
'billing_address_1' => $order->billing_address_1 ." ".$order->billing_address_2,
'billing_postcode' => $order->billing_postcode,
'delivery_tel_no'=> $order->billing_phone,
'delivery_contact'=> $order->billing_first_name,
This outputs;
H,HOME,"2015-05-13 13:19:46",REAL,,,,,"Ben Bull","Address 1 Address2",
Some are surround by "" and some aren't how do we get them all to be?
For CSV output, you need to enclose all the values with double quotes. In addition, if the values have double quotes inside them you need to escape those double quotes by using two consecutive double quotes. That's how CSV works.
Check this PHP function below.
function makeCSV($value) {
//Encloses each token (Before and after)
$CSV_TOKEN_ENCLOSER = '"';
//Used to escape the enclosing character if inside the token
$CSV_TOKEN_ENCLOSER_ESCAPER = '""';
//Escape the encloser inside the value
$csv_value = str_replace($CSV_TOKEN_ENCLOSER, $CSV_TOKEN_ENCLOSER_ESCAPER, $value);
//Enclose the value
$csv_value .= $CSV_TOKEN_ENCLOSER . $csv_value . $CSV_TOKEN_ENCLOSER;
//Return
return $csv_value;
}
This does the job as I've explained in the first paragraph. You can use it as such in your case:
$order_data = array(
'type' => makeCSV("H"),
'order_type' => makeCSV('HOME'),
'order_date' => makeCSV($order->order_date),
...
);
However, it looks like you have code that's enclosing the values from your order objects within quotes automatically for you. I suggest you avoid that code, replace that with the usage of the makeCSV function presented above, and then finally just use a standard PHP implode call to get your CSV like this:
$comma_separated_csv = implode(",", $order_data);
Hope this helps.
Cheers.
Try to force all types to string like:
'order_type' => (string) 'HOME'
I have this link that works.
echo '<a href="?country=Estonia&from_language=Russian&into_language=Latvian&submitted=true&
page='.$x. '">'.$x.'</a> ';
But I need the nouns Estonia, Russian and Latvian replaced by scalar variables like $country, $from_language, $into_language.
I have tried all possible combinations of dots and single and double quotes. I always get syntax errors. I don't know how the embed the variables there.
Anybody knows?
thank you
Do yourself a massive favour and use http_build_queryDocs:
<a href="?<?php echo http_build_query(array(
'country' => $country,
'fromLanguage' => $fromLanguage,
'somethingElse' => $somethingElse,
'...' => '...'
), '', '&'); ?>">Link</a>
use something easy one like sprintf or printf.
eg:
printf('<a href="?country=%s&from_language=%s&into_language=%s&submitted=true&
page=%s">%s</a>', $country, $fromLanguage, $toLanguage, $pageID, $dispText);
You could also use something like encoding with double quote sign like:
echo "<a href=\"?country={$country}&from_language={$fromLanguage}&into_language={$toLanguage}&submitted=true&
page={$pageID}\">{$dispText}</a>"
Avoid to put variables directly into string when not extremely simple. Use concatenation instead, and escape string if you want to make something good:
echo '<a href="?country=' . htmlentities($country) .
'&from_language=' . htmlentities($from_language) .
'&into_language=' . htmlentities($into_language) .
'&submitted=true&page=' . intval($x) . '">' . htmlentities($x) . '</a> ';
Anyway, if you really want it the complex way, you have to consider that you need doble quotes for HTML attributes, but double quotes are needed to wrap the PHP string because you want to put variables in it. So, you must escape HTML double quotes. Try:
echo "' . $x . ' ';
Combining the answers of Corbin and KoolKabin gives you this easy-to-read snippet:
printf('%s',
htmlspecialchars(
http_build_query(array(
'country' => $country,
'from_language' => $from_language,
'into_language' => $into_language,
'submitted' => 'true',
'page' => $x
))
),
htmlspecialchars($x));
Parametrization
printf and sprintf are very useful for adding parameters to strings. They make it easy to add escaping or complex values without making the string itself unreadable. You can always see at a glance what string it is by the first parameter.
http_build_query is also a way of parametrizing, but for the querystring. The main use is that you don't need to focus on the syntax of querystrings at all.
Escaping
htmlspecialchars makes sure that the data is fit for insertion into HTML code. It's similar to escaping in SQL queries to avoid SQL injections, only here we want to avoid HTML injections (also called XSS or cross-site scripting).
http_build_query will automatically make sure that all values are escaped for insertion as an URL in the address field in a browser. This does not guarantee fitness for insertion into HTML code. htmlspecialchars is therefore needed for the querystring as well!
If you scripts output HTML, consider to configure the output setting for argument separators arg_separator.output:
ini_set('arg_separator.output', '&');
You can then simply create the URI query info path by using http_build_query:
$country = 'de';
$fromLanguage = 'en_EN';
?>
Link
Which will give you a perfectly validly encoded output, which is immune to injections:
Link
Full Demo
$country = 'Estonia';
$from_language = 'Russian';
$into_language = 'Latvian';
echo ''.$x.' ';
OR
echo "$x";
OR
echo "{$x}";
I know I can refer in replacement to dynamic parts of the term in regex in PHP:
preg_replace('/(test1)(test2)(test3)/',"$3$2$1",$string);
(Somehow like this, I don't know if this is correct, but its not what I am looking for)
I want that in the regex, like:
preg_match_all("~<(.*)>.*</$1>~",$string,$matches);
The first part between the "<" and ">" is dynamic (so every tag existing in html and even own xml tags can be found) and i want to refer on that again in the same regex-term.
But it doesn't work for me. Is this even possible?
I have a server with PHP 5.3
/edit:
my final goal is this:
if have a html-page with e. g. following source-code:
HTML
<html>
<head>
<title>Titel</title>
</head>
<body>
<div>
<p>
p-test<br />
br-test
</p>
<div>
<p>
div-p-test
</p>
</div>
</div>
</body>
</html>
And after processing it should look like
$htmlArr = array(
'html' => array(
'head' => array('title' => 'Titel'),
'body' => array(
'div0' => array(
'p0' => 'p-test<br />br-test',
'div1' => array(
'p1' => 'div-p-test'
)
)
)
));
Placeholders in the replacement string use the $1 syntax. In the regex itself they are called backreferences and follow the syntax \1 backslash and number.
http://www.regular-expressions.info/brackets.html
So in your case:
preg_match_all("~<(.*?)>.*?</\\1>~",$string,$matches);
The backslash is doubled here, because in PHP strings the backslash escapes itself. (In particular for double quoted strings, else it would become an ASCII symbol.)
This is a follow-up question to the one I posted here (thanks to mario)
Ok, so I have a preg_replace statement to replace a url string with sometext, insert a value from a query string (using $_GET["size"]) and insert a value from a associative array (using $fruitArray["$1"] back reference.)
Input url string would be:
http://mysite.com/script.php?fruit=apple
Output string should be:
http://mysite.com/small/sometext/green/
The PHP I have is as follows:
$result = preg_replace('|http://www.mysite.com/script.php\?fruit=([a-zA-Z0-9_-]*)|e', ' "http://www.mysite.com/" .$_GET["size"]. "/sometext/" .$fruitArray["$1"]. "/"', $result);
This codes outputs the following string:
http://mysite.com/small/sometext//
The code seems to skip the value in $fruitArray["$1"].
What am I missing?
Thanks!
Well, weird thing.
Your code work's perfectly fine for me (see below code that I used for testing locally).
I did however fix 2 things with your regex:
Don't use | as a delimiter, it has meaning in regex.
Your regular expression is only giving the illusion that it works as you're not escaping the .s. It would actually match http://www#mysite%com/script*php?fruit=apple too.
Test script:
$fruitArray = array('apple' => 'green');
$_GET = array('size' => 'small');
$result = 'http://www.mysite.com/script.php?fruit=apple';
$result = preg_replace('#http://www\.mysite\.com/script\.php\?fruit=([a-zA-Z0-9_-]*)#e', ' "http://www.mysite.com/" .$_GET["size"]. "/sometext/" .$fruitArray["$1"]. "/"', $result);
echo $result;
Output:
Rudis-Mac-Pro:~ rudi$ php tmp.php
http://www.mysite.com/small/sometext/green/
The only thing this leads me to think is that $fruitArray is not setup correctly for you.
By the way, I think this may be more appropriate, as it will give you more flexibility in the future, better syntax highlighting and make more sense than using the e modifier for the evil() function to be internally called by PHP ;-) It's also a lot cleaner to read, IMO.
$result = preg_replace_callback('#http://www\.mysite\.com/script\.php\?fruit=([a-zA-Z0-9_-]*)#', function($matches) {
global $fruitArray;
return 'http://www.mysite.com/' . $_GET['size'] . '/sometext/' . $fruitArray[$matches[1]] . '/';
}, $result);
i write it again, i don't understand good where is the error, the evaluation of preg results is very weird in php
preg_replace(
'|http\://([\w\.-]+?)/script\.php\?fruit=([\w_-]+)|e'
, '"http://www.$1/".$_GET["size"]."/sometext/".$fruitArray["$2"]."/";'
, $result
);
It looks like you have forgotten to escape the ?. It should be /script.php\?, with a \? to escape properly, as in the linked answer you provided.
$fruitArray["\$1"] instead of $fruitArray["$1"]