how to properly use incremental array variable inside str_replace() in PHP - php

I am trying to create pdf from the values of a dynamic form.
I am collecting and storing dynamic inputs like this.
$inputarray = array();
foreach ($_POST['input'] as $input) {
$inputarray[] = $input;
}
Now I want to replace a template with the values collected from the form. My current codes look like this.
//count total number of inputs
$icount = count($_POST['input']);
//replace template with values
ob_start();
$require_once 'template.php';
$html = ob_get_clean();
$template = str_replace(array('%name%', '%input0%', '%input1%', '%input2%'), array($name, $inputarray[0], $inputarray[1], $inputarray[2]), $html);
The code of my template.php looks like this.
<tr><td>%name%</td></tr>
<?php
for ($i=0; $i<$icount; $i++){
echo '<tr>';
echo '<td>%input'.$i.'%</td>';
echo '</tr>';
?>
My code is working fine if I use %input1%, %input2% manually. My question is how do I automate that part?
P.S: I am still in beginning stage of learning and not proficient in object-oriented style. If possible, please explain in procedural style.
Edit: I don't understand why my question is closed. I would really like to know from someone that which part of my question is not understandable. English is not my first language and if some parts are not clear enough, at least I deserve specific feedback, not something general like "your question is not clear".

Something like this should work:
$search = array();
$search[] = '%name%';
$replace = array();
$replace[] = $name;
// make sure $_POST['input'] is zero-indexed, otherwise apply `array_values`
foreach ($_POST['input'] as $key => $input) {
$search[] = '%input' . $key . '%';
$replace[] = $input;
}
// next
$template = str_replace($search, $replace, $html);

You can also try this.
$template = '%input2% %input1% %input0% %name%';
$inputarray = [ 'another', "is", "This" ];
foreach ($inputarray as $key => $value) {
$replacement [ '%input'.$key.'%' ] = $value ;
}
$replacement[ "%name%" ] = 'example';
$template = strtr( $template, $replacement );

Related

Extract everything within brackets

I have a string of HTML with tags inside saved in the database e.g:
<p>Hello {$name}, welcome to {$shop_name}....</p>
I want to replace all of the tags with real data, now at the moment I loop through all available data and replace if it exists.
foreach($data as $key => $data){
$content = str_replace('{$'.$key.'}', $data, $content);
}
Is there a better way of doing this without looping through all of the $data? This is now growing to over 5000 rows.
I mean is it possible to extract all variables {$name}/{$shop_name} then do a replace on only the found?
You can do it with a single str_replace call.
$find = array();
$replace = array();
foreach($data as $key => $data) {
$find[] = "\{$" . $key . "}";
$replace[] = $data;
}
$content = str_replace($find, $replace, $content);
Unless there is a real performance issue, I wouldn't worry about it too much.
str_replace accepts arrays, you can build the array with array_keys, array_values and user array_map to add the {$}
$content = str_replace(
array_map(function($e) { return '{$' . $e . '}';}, array_keys($data)),
array_values($data),
$content);
Can just do
$content = preg_replace('/\{$(\w+)\}/e', '$data[\'$1\']', $content);

Concatenation of exploded array of tags to a string with links

With my custom function below, my aim is to give a specific link to each element of array of tags. My input to the function is a string like (tag1, tag2, tag3). My output is (in linked form) tag1,
“tag1,” is okey but why can not I get what I expect : “tag1, tag2, tag3” (in linked form)
I read examples in php.net and in this site for the terms (array, explode, for, .=) but I couldn’t solve my issue.
Can you guide me please
function tag_linkify ($article_tags)
{
$array_of_tags = explode(",", $article_tags);
$sayac = count($array_of_tags);
$linked_tags ="";
for ($i=0; $i<$sayac; $i++)
{
$linked_tags .= ''.$array_of_tags[$i].', ';
}
echo substr_replace($linked_tags, '', -1, 2);
}
tag_linkify (tag1,tag2,tag3);
ThanksRegards
Improving on Sedz post:
function tag_linkify ($article_tags)
{
$array_of_tags = explode(",", $article_tags);
echo '' . implode(',', $array_of_tags) . '';
}
tag_linkify ("tag1,tag2,tag3");
Btw. the parameters in your tag_linkify call miss their quotation marks and
'<a href="'.'">'
is really the same as
'<a href="">'
If i understand your question correctly i would do:
tag_linkify ($tag1, $tag2, $tag3);
function tag_linkify ()
{
$tags = get_func_args(); // get all tags in an array
$final = '';
// loop through the tags
forech($tags as $tag)
{
// return or echo depends on what you doing with your data
$final .=''. $tag . '';
}
return $final;
}
get_func_args
Check this out with use of implode
function tag_linkify ()
{
$array_of_tags = get_func_args();;
$sayac = count($array_of_tags);
$linked_tags =array();
for ($i=0; $i<$sayac; $i++)
{
$linked_tags[] = ''.$array_of_tags[$i].' ';
}
echo "(".implode(',', $lined_tags).")";
}
tag_linkify (tag1,tag2,tag3);
I hope this can help

Checking if an index in a multidimensional array is an array

The code:
$row['text'] = 'http://t.co/iBSiZZD4 and http://t.co/1rG3oNmc and http://t.co/HGFjwqHI and http://t.co/8UldEAVt';
if(preg_match_all('|http:\/\/t.co\/.{1,8}|i',$row['text'],$matches)){
foreach($matches[0] as $value){
$headers = get_headers($value,1);
if(is_array($headers['Location'])){
$headers['Location'] = $headers['Location'][0];
}
$row['text'] = preg_replace('|http:\/\/t.co\/.{1,8}|i', '' . $headers['Location'] . '',$row['text']);
}
}
This is related to get_headers(). Sometimes get_headers($url,1) returns an array with a location index key like so: [Location]=>Array([0]=>url1 [1]=>url2). I basically want to make [Location] equal to [Location][0] if [Location][0] exists. However, the above code doesn't seem to accomplish that task. I've also tried array_key_exists() and isset() but neither solved the problem. Thoughts?
Don't try to replace on the fly. First get all the values, and then do the replace in one batch (using two arrays as the $search and $replace parameters).
<?php
$replace = array();
$row = array('text' => 'http://t.co/iBSiZZD4 and http://t.co/1rG3oNmc and http://t.co/HGFjwqHI and http://t.co/8UldEAVt');
if (preg_match_all('|http:\/\/t.co\/.{1,8}|i', $row['text'], $search)) {
foreach ($search[0] as $value) {
$headers = get_headers($value, 1);
if (is_array($headers['Location'])) {
$headers['Location'] = $headers['Location'][0];
}
$replace[] = "<a href='{$headers["Location"]}'>{$headers["Location"]}</a>";
}
$row['text'] = str_replace($search[0], $replace, $row['text']);
echo $row["text"];
}
P.S. - Next time, please tell us the context of your problem, tell us you "are making a service that resolves shortened URLs", don't let me figure that out from your code alone.

How to parse PHP code in a PHP array?

I am using this piece of code on a site of mine.
If there is PHP code in the array and if you echo it, it does not run.
There is piece of code;
function spin($var){
$words = explode("{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
echo $word." ";
}
}
}
$text = "example.com is {the best forum|a <? include(\"myfile.php\");?>Forum|a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
The file that needs to be included "myfile.php" will not be included. and the PHP codes will be visible. Why is that? How can I solve this problem?
I believe that you will want to run the include statement through eval(). However note that:
"The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand." (PHP.net)
SOURCE: http://php.net/manual/en/function.eval.php
You might try the following:
<?php
function spin($var)
{
$words = explode("\{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
if ( preg_match( "/\<\? include\(\\\"([A-Za-z\.]+)\\\"\)\;\?\>/", $word ) )
{
$file = preg_replace( "/^.*\<\? include\(\\\"([A-Za-z\.]+)\\\"\)\;\?\>.*\$/", "\$1", $word );
$pre = preg_replace( "/^(.*)\<\? include\(\\\"[A-Za-z\.]+\\\"\)\;\?\>.*\$/", "\$1", $word );
$post = preg_replace( "/^.*\<\? include\(\\\"[A-Za-z\.]+\\\"\)\;\?\>(.*)\$/", "\$1", $word );
echo $pre;
include( $file );
echo $post;
}
}
}
}
$text = "example.com is {the best forum|a <? include(\"myfile.php\");?>Forum|a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
?>
My suggestion is a bit of other way,
function spin($var){
$words = explode("{",$var);
foreach ($words as $word)
{
$words = explode("}",$word);
foreach ($words as $word)
{
$words = explode("|",$word);
$word = $words[array_rand($words, 1)];
if(str_replace(" ","",$word) == 'thisparam'){
echo 'a';
include("myfile.php");
echo 'Forum';
}else{
echo $word." ";
}
}
}
}
$text = "example.com is {the best forum| thisparam |a wonderful Forum|a perfect Forum} {123|some other sting}";
spin($text);
where thisparam is you variable $test is the parameter to run the if statement.
I place a str_replace infront of $word to replace strings to get exact word.
Well it is just a string of text after all. The echo will just output the text...
I suggest you look to make use of eval http://php.net/manual/en/function.eval.php
I cant really tell why you wish to do this though. Whenever I need to use eval and friends I stop to think "Should I be doing this?"

php associative arrays, regex, array

I currently have the following code :
$content = "
<name>Manufacturer</name><value>John Deere</value><name>Year</name><value>2001</value><name>Location</name><value>NSW</value><name>Hours</name><value>6320</value>";
I need to find a method to create and array as name=>value. E.g Manufacturer => John Deere.
Can anyone help me with a simple code snipped I tried some regex but doesn't even work to extract the names or values, e.g.:
$pattern = "/<name>Manufacturer<\/name><value>(.*)<\/value>/";
preg_match_all($pattern, $content, $matches);
$st_selval = $matches[1][0];
You don't want to use regex for this. Try out something like SimpleXML
EDIT
Well, why don't you start with this:
<?php
$content = "<root>" . $content . "</root>";
$xml = new SimpleXMLElement($c);
print_r($xml);
?>
EDIT 2
Despite the fact that some of the answers posted using regular expression MAY work, you should get in the habit of using the correct tool for the job and regular expressions are not the correct tool for parsing of XML.
I'm using your $content variable:
$preg1 = preg_match_all('#<name>([^<]+)#', $content, $name_arr);
$preg2 = preg_match_all('#<value>([^<]+)#', $content, $val_arr);
$array = array_combine($name_arr[1], $val_arr[1]);
This is rather simple, can be solved by regex. Should be:
$name = '<name>\s*([^<]+)</name>\s*';
$value = '<value>\s*([^<]+)</value>\s*';
$pattern = "|$name $value|";
preg_match_all($pattern, $content, $matches);
# create hash
$stuff = array_combine($matches[1], $matches[2]);
# display
var_dump($stuff);
Regards
rbo
First of all, never use regex to parse xml...
You could do this with an XPATH query...
First, wrap the content in a root tag to make the parser happy (if it doesn't already have it):
$content = '<root>' . $content . '</root>';
Then, load the document
$dom = new DomDocument();
$dom->loadXml($content);
Then, initialize the XPATH
$xpath = new DomXpath($dom);
Write your query:
$xpathQuery = '//name[text()="Manufacturer"]/follwing-sibling::value/text()';
Then, execute it:
$manufacturer = $xpath->evaluate($xpathQuery);
If I did the xpath right, it $manufacturer should be John Deere...
You can see the docs on DomXpath, a basic primer on XPath, and a bunch of XPath examples...
Edit: That won't work (PHP doesn't support that syntax (following-sibling). You could do this instead of the xpath query:
$xpathQuery = '//name[text()="Manufacturer"]';
$elements = $xpath->query($xpathQuery);
$manufacturer = $elements->item(0)->nextSibling->nodeValue;
I think this is what you're looking for:
<?php
$content = "<name>Manufacturer</name><value>John Deere</value><name>Year</name><value>2001</value><name>Location</name><value>NSW</value><name>Hours</name><value>6320</value>";
$pattern = "(\<name\>(\w*)\<\/name\>\<value\>(\w*)\<\/value\>)";
preg_match_all($pattern, $content, $matches);
$arr = array();
for ($i=0; $i<count($matches); $i++){
$arr[$matches[1][$i]] = $matches[2][$i];
}
/* This is an example on how to use it */
echo "Location: " . $arr["Location"] . "<br><br>";
/* This is the array */
print_r($arr);
?>
If your array has a lot of elements dont use the count() function in the for loop, calculate the value first and then use it as a constant.
I'll edit as my PHP is wrong, but here's some PHP (pseudo-)code to give some direction.
$pattern = '|<name>([^<]*)</name>\s*<value>([^<]*)</value>|'
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);
for($i = 0; $i < count($matches); $i++) {
$arr[$matches[$i][1]] = $matches[$i][2];
}
$arr is the array you want to store the name/value pairs.
Using XMLReader:
$content = '<name>Manufacturer</name><value>John Deere</value><name>Year</name><value>2001</value><name>Location</name><value>NSW</value><name>Hours</name><value>6320</value>';
$content = '<content>' . $content . '</content>';
$output = array();
$reader = new XMLReader();
$reader->XML($content);
$currentKey = null;
$currentValue = null;
while ($reader->read()) {
switch ($reader->name) {
case 'name':
$reader->read();
$currentKey = $reader->value;
$reader->read();
break;
case 'value':
$reader->read();
$currentValue = $reader->value;
$reader->read();
break;
}
if (isset($currentKey) && isset($currentValue)) {
$output[$currentKey] = $currentValue;
$currentKey = null;
$currentValue = null;
}
}
print_r($output);
The output is:
Array
(
[Manufacturer] => John Deere
[Year] => 2001
[Location] => NSW
[Hours] => 6320
)

Categories