how to parse variable inside string?
here is a sample code that works:
$str = "12345";
$str2 = "STR:{$str}";
$str3 = $str2;
echo $str2;
echo $str3;
but these won't work:
$otp = 12345;
$template = MessageTemplate::where('type',1)->first(); //db query
$message = $template->content; //content field, "OTP:{$otp}"
echo $message;
this code prints OTP:{$otp} instead of OTP:12345
these is what we need:
$member = Member::where('id',$id)->with('position')->with('company')->first();
$otp = 12345;
$template = MessageTemplate::where('type',1)->first(); //db query
$message = $template->content; //content field, "OTP:{$otp}"
$sms = Sms::Create(['mobile'=>$member->mobile,'message'=>$message]);
this code prints OTP:{$otp} instead of OTP:12345
Thanks for your responses. Actually what i need is to parse it before saving it to the database. the string "OTP:12345" should be written back to the databse. and also, variables are dynamic. It is a template to allow admin to customize the message, so the admin can add as many variable as he/she want. For ex:
"{$member->title},{$member->firstName}, {$member->lastName}, in order to verify that you are {$mamber->position->name} of {$member->company->name}. enter code {$otp}".
so i can't use str_replace. and also our db supports json so admin can add a custom attribute to $member
You can use mutators in your model like this
// MessageTemplate class
public function getContentAttribute($string)
{
return 'OTP:' . $string;
}
// anywhere in controller
$message = $template->content; // will call content mutator
echo $message;
The value of $template->content is just a string.
You can simply do a replace:
$message = str_replace('{$otp}', $otp, $template->content);
Related
I have a PHP code which sends an email with HTML template.
HTML template has some PHP variable like Name, Email, etc.
<strong>Name: {name} </strong>
because email template has more code, I include it in my PHP file
$htmlInvoice = file_get_contents($_SERVER["DOCUMENT_ROOT"] .'/mail/invoice.html');
$name= $user['name']);
$msg = $htmlInvoice;
But when an email sent, it can not read variables inside the
HTML file. and for example echo $name like a text
You can use strtr for this. For e.g:
<?php
$a = 'Hi this is {name}. I am writing {language}';
echo strtr($a, ['{name}' => 'Abhishek', '{language}' => 'php']);
Strtr
You need to replace the {name} string for your desired output.
$htmlInvoice = file_get_contents($_SERVER["DOCUMENT_ROOT"] .'/mail/invoice.html');
$name= $user['name']);
$msg = str_replace('{name}',$name, $htmlInvoice);
You could change /mail/invoice.html to include PHP commands.
<strong><? echo $user['name'] ?></strong>
Then
$htmlInvoice = file_get_contents($_SERVER["DOCUMENT_ROOT"] .'/mail/invoice.html');
$msg = _readphp_eval($htmlInvoice);
function _readphp_eval($code) {
ob_start();
print eval('?>'. $code);
$output = ob_get_contents();
ob_end_clean();
return $output;
}
I don't know who to attribute _readphp_eval($code) function to ... It is floating around the internet, and works very nicely for this purpose.
It would require that $user['name'] be defined/included in the invoice.html file.
I am working on a script with templates. So I have this PHP code:
<?php
$string = "TEST";
echo(file_get_contents('themes/default/test.html'));
?>
And I have this HTML (the test.html file):
<html>
<p>{$string}</p>
</html>
How can I make PHP actually display the variable inside the curly brackets? At the moment it displays {$string}.
P.S:
The string might also be an object with many many variables, and I will display them like that: {$object->variable}.
P.S 2: The HTML must stay as it is. This works:
$string = "I'm working!"
echo("The string is {$string}");
I need to use the same principle to display the value.
You can use the following code to achieve the desired result:
<?php
$string = "TEST";
$doc = file_get_contents('themes/default/test.html'));
echo preg_replace('/\{([A-Z]+)\}/', "$$1", $doc);
?>
P.S. Please note that it will assume that every string wrapped in { }
has a variable defined. So No error checking is implemented in the code above. furthermore it assumes that all variables have only alpha characters.
If it is possible to save your replacees in an array instead of normal variables you could use code below. I'm using it with a similar use case.
function loadFile($path) {
$vars = array();
$vars['string'] = "value";
$patterns = array_map("maskPattern", array_keys($vars));
$result = str_replace($patterns, $vars, file_get_contents($path));
return $result;
}
function maskPattern($value) {
return "{$" . $value . "}";
}
All you PHP must be in a <?php ?> block like this:
<html>
<p><?php echo "{" . $string . "}";?></p>
</html>
If you know the variable to replace in the html you can use the PHP function 'str_replace'. For your script,
$string = "TEST";
$content = file_get_contents('test.html');
$content = str_replace('{$string}', $string, $content);
echo($content);
It's simple to use echo.
<html>
<p>{<?php echo $string;?>}</p>
</html>
UPDATE 1:
After reading so many comments, found a solution, try this:
$string = "TEST";
$template = file_get_contents('themes/default/test.html', FILE_USE_INCLUDE_PATH);
$page = str_replace('{$string}',$string,$template);
echo $page;
I am using Laravel to create a web bot that collects data from other websites and stores it in my MySQL database. When I want to save body I use dd($this->render($post)); and it is good. Yet, when I use $post->save() for saving my post in db, it not saving the body of my post completely and some of text is missing.
My body is at least 10000 characters and I always have this problem.
I checked text and longtext for body column type and is not there any difference...
Where is problem?
edit :
this is my index method :
public function getIndex()
{
$temp = App\Temp::where('status' , 0)->orderBy('id' , 'desc')->first();
$temp->status = 1;
$temp->save();
$post = new App\Post;
$post->title = $temp->title;
$post->link = $temp->link;
$post->desc = $temp->desc;
$post->cat_id = $temp->cat_id;
$post->url_id = $temp->url_id;
$post->body = $this->render($post);
$post->save();
echo "+";
}
When I am using dd($this->render($post)); before save, it shows full text without any problem... but after save when I fetch the body, some characters is missing from the end of post...
and this is render() method...
public function render($post)
{
echo "Start : ";
$this->ftp->createFolder('/'.$post->url_id.'/'.$post->id."/");
echo "Dir - ";
$mixed_body = $this->desc($post->title);
echo "Mix - ";
$body ="";
$body = $body . '<h3><a href='.$this->postUrl.'>'.$this->postTitle.'</a></h3>';
echo "Title - ";
while(strlen($mixed_body) > 100)
{
$body = $body . $this->randImage($post);
$body = $body . $this->randTitle();
//insert a random paragraph
$number = rand(100 , strlen($mixed_body));//temporary
$paragraph = substr($mixed_body , 0 , $number);
$mixed_body = substr($mixed_body , $number , strlen($mixed_body)-$number);
$body = $body . '<p>' . $paragraph . '</p>';
echo "P|";
}
echo "\nDone : ".strlen($body);
return $body;
}
others methods in render() are appending some text to $body and those are not important.
and my model :
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
public function tags()
{
return $this->hasMany('App\Tag');
}
}
I find my problem reason...
sometimes I have a character like � in my body that laravel not saves the characters after it...
I find to use this line to delete � character...
$post->body = mb_convert_encoding($this->render($post), 'UTF-8', 'UTF-8');
thanks from all to help me, I have a very bad headache and want to rest...
thanks from all again, good night/morning/afternoon (according to your time-zones) :)
I am trying to use data entered by the user to store it into an XML Database file for use further down the line. However, for some reason I continue to get this error.
The problem code is summarised below and the whole PHP file is below that for context.
I have tried converting the integer I got (I was using mt_rand() before using uniqid()) using strval(), also tried Type Casting to (string), even tried Type Casting to (object). All no luck. uniqid() returns a string already. In fact, the error returned when I try Type Casting to object (both from uniqid() and mt_rand()) was different, and made life confusing:
[![Error 2 Where the output of idGenerated is an object][2]][2]
Why oh why does a createTextNode hate Strings, Integers AND Objects?? And why do the other variables in the file (undergoing the SAME process) pass by absolutely fine?
Summarised Problem Code
$idGenerated = uniqid();
$dom = new DOMDocument();
$dom->load('../test.xml');
$idDec = $dom->createTextNode($idGenerated);
$id->appendChild($idDec);
$messageElement->appendChild($id);
Whole File:
<?php
session_start();
//Generate random number to avoid overwrite of file
$randomNumber = mt_rand(10, 99);
move_uploaded_file($_FILES['attachment'][tmp_name], "../uploads/" . $randomNumber . $_FILES['attachment'][name]);
//General Variables
***$idGenerated = uniqid();***
$currentDate = date('l jS \of F h:i:s A');
$sender = $_SESSION['user'];
$message = $_POST['messageText'];
$up_file = $randomNumber . $_FILES['attachment'][name];
$up_file_location = "uploads/" . $up_file;
echo "<br>";
var_dump($currentDate);
echo "<br>";
var_dump($sender);
echo "<br>";
var_dump($message);
echo "<br>";
var_dump($up_file);
echo "<br>";
var_dump($up_file_location);
$dom = new DOMDocument();
$dom->load('../test.xml');
//Dom Variable Declarations
//Declare String Data
***$idDec = $dom->createTextNode($idGenerated);***
$date = $dom->createTextNode($currentDate);
$name = $dom->createTextNode($sender);
$messageText = $dom->createTextNode($message);
$link = $dom->createTextNode($up_file_location);
$linkName = $dom->createTextNode($up_file);
//Declare Data Elements
$id = $dom->createElement('id');
$timecode = $dom->createElement('timecode');
$author = $dom->createElement('author');
$content = $dom->createElement('content');
$filePath = $dom->createElement('filePath');
$fileName = $dom->createElement('fileName');
$messageElement = $dom->createElement('message');
//Create XML Data Structure
//ID
***$id->appendChild($idDec);***
//Date
$timecode->appendChild($date);
//Name
$author->appendChild($name);
//Message
$content->appendChild($messageText);
//File (if there is one!)
$filePath->appendChild($link);
$fileName->appendChild($linkName);
//Message Wrapper Element
***$messageElement->appendChild($id);***
$messageElement->appendChild($timecode);
$messageElement->appendChild($author);
$messageElement->appendChild($content);
$messageElement->appendChild($filePath);
$messageElement->appendChild($fileName);
//Load last existing XML entry for reference (which, since they are all in reverse order, will actually be the FIRST entry in the database)
$xml = simplexml_load_file('../test.xml');
$lastEntry = $xml->log->message[0];
//Place new data BEFORE the last existing message Element
$newEntry = $dom->firstChild->appendChild($messageElement);
$lastEntry->parentNode->insertBefore($newEntry, $lastEntry);
$dom->save('../test.xml');
header("Location: ../index.php");
?>
Whenever you get Call to a member function … on a non-object, you’re using something as an object which at the time of calling is not an object. (This often seen in loops where you access a array element, expecting it to be an object when it’s not.)
But in your case, it’s simply the fact that $messageElement is not defined. Maybe you copy/pasted the code from somewhere else and forgot to copy the initial definition/initialisation of the $messageElement variable.
I'm including a file in one of my class methods, and in that file has html + php code. I return a string in that code. I explicitly wrote {{newsletter}} and then in my method I did the following:
$contactStr = include 'templates/contact.php';
$contactStr = str_replace("{{newsletter}}",$newsletterStr,$contactStr);
However, it's not replacing the string. The only reason I'm doing this is because when I try to pass the variable to the included file it doesn't seem to recognize it.
$newsletterStr = 'some value';
$contactStr = include 'templates/contact.php';
So, how do I implement the string replacement method?
You can use PHP as template engine. No need for {{newsletter}} constructs.
Say you output a variable $newsletter in your template file.
// templates/contact.php
<?= htmlspecialchars($newsletter, ENT_QUOTES); ?>
To replace the variables do the following:
$newsletter = 'Your content to replace';
ob_start();
include('templates/contact.php');
$contactStr = ob_get_clean();
echo $contactStr;
// $newsletter should be replaces by `Your content to replace`
In this way you can build your own template engine.
class Template
{
protected $_file;
protected $_data = array();
public function __construct($file = null)
{
$this->_file = $file;
}
public function set($key, $value)
{
$this->_data[$key] = $value;
return $this;
}
public function render()
{
extract($this->_data);
ob_start();
include($this->_file);
return ob_get_clean();
}
}
// use it
$template = new Template('templates/contact.php');
$template->set('newsletter', 'Your content to replace');
echo $template->render();
The best thing about it: You can use conditional statements and loops (full PHP) in your template right away.
Use this for better readability: https://www.php.net/manual/en/control-structures.alternative-syntax.php
This is a code i'm using for templating, should do the trick
if (preg_match_all("/{{(.*?)}}/", $template, $m)) {
foreach ($m[1] as $i => $varname) {
$template = str_replace($m[0][$i], sprintf('%s', $varname), $template);
}
}
maybe a bit late, but I was looking something like this.
The problem is that include does not return the file content, and easier solution could be to use file_get_contents function.
$template = file_get_contents('test.html', FILE_USE_INCLUDE_PATH);
$page = str_replace("{{nombre}}","Alvaro",$template);
echo $page;
based on #da-hype
<?php
$template = "hello {{name}} world! {{abc}}\n";
$data = ['name' => 'php', 'abc' => 'asodhausdhasudh'];
if (preg_match_all("/{{(.*?)}}/", $template, $m)) {
foreach ($m[1] as $i => $varname) {
$template = str_replace($m[0][$i], sprintf('%s', $data[$varname]), $template);
}
}
echo $template;
?>
Use output_buffers together with PHP-variables. It's far more secure, compatible and reusable.
function template($file, $vars=array()) {
if(file_exists($file)){
// Make variables from the array easily accessible in the view
extract($vars);
// Start collecting output in a buffer
ob_start();
require($file);
// Get the contents of the buffer
$applied_template = ob_get_contents();
// Flush the buffer
ob_end_clean();
return $applied_template;
}
}
$final_newsletter = template('letter.php', array('newsletter'=>'The letter...'));
<?php
//First, define in the template/body the same field names coming from your data source:
$body = "{{greeting}}, {{name}}! Are You {{age}} years old?";
//So fetch the data at the source (here we will create some data to simulate a data source)
$data_source['name'] = 'Philip';
$data_source['age'] = 35;
$data_source['greeting'] = 'hello';
//Replace with field name
foreach ($data_source as $field => $value) {
//$body = str_replace("{{" . $field . "}}", $value, $body);
$body = str_replace("{{{$field}}}", $value, $body);
}
echo $body; //hello, Philip! Are You 35 years old?
Note - An alternative way to do the substitution is to use the commented syntax.
But why does using the three square brackets work?
By default the square brackets allow you to insert a variable inside a string.
As in:
$name = 'James';
echo "His name is {$name}";
So when you use three square brackets around your variable, the innermost square bracket is dedicated to the interpolation of the variables, to display their values:
This {{{$field}}} turns into this {{field}}
Finally the replacement with str_replace function works for two square brackets.
no, don't include for this. include is executing php code. and it's return value is the value the included file returns - or if there is no return: 1.
What you want is file_get_contents():
// Here it is safe to use eval(), but it IS NOT a good practice.
$contactStr = file_get_contents('templates/contact.php');
eval(str_replace("{{newsletter}}", $newsletterStr, $contactStr));