I'm working on a new project. I route everything to router.php, but I have a problem now. I'm using keywords, so I can use:
<[DEFAULT_JS]>
And the return is:
<script src="./assets/js/jquery-1.11.0.min.js" type="text/javascript"></script>
This is the code:
// some code
if(in_array($_GET['p'], $allowedPages)) {
$source = file_get_contents('./pages/'.$allowedPages[$_GET['p']]);
foreach($keywords as $key => $value) {
$source = str_replace("<[".$key."]>", $value, $source);
}
echo $source;
} else {
// some code
You can see, I'm using file_get_contents to get the script and replace the 'keywords', but now it won`t send GET data with the page. When I use include it should work but then I cannot use the 'keywords' anymore.
So, how can include a file and replace the keywords?
So basically you are inventing some template system and you want to use PHP in your templates?
I think that you can use eval() function for that. But it's still not a good option.
// some code
if(in_array($_GET['p'], $allowedPages)) {
$source = file_get_contents('./pages/'.$allowedPages[$_GET['p']]);
foreach($keywords as $key => $value) {
$source = str_replace("<[".$key."]>", $value, $source);
}
eval($source);
} else {
// some code
Related
I'm having an issue with php file_get_content(), I have a txt file with links where I created a foreach loop that display multiple links in the same webpage but it's not working, please take a look at the code:
<?php
$urls = file("links.txt");
foreach($urls as $url) {
file_get_contents($url);
echo $url;
}
The content of links.txt is: https://www.google.com
Result: Only a String displaying "https://www.google.com"
Another code that works is :
$url1 = file_get_contents('https://google.com');
echo $url1;
This code returns google's homepage, but I need to use first method with loops to provide multiple links.
Any idea?
Here's one way of combining the things you already had implemented:
$urls = file("links.txt");
foreach($urls as $url) {
$contents = file_get_contents($url);
echo $contents;
}
Both file and file_get_contents are functions that return some value; what you had to do is putting return value of the latter one inside a variable, then outputting that variable with echo.
In fact, you didn't even need to use variable: this...
$urls = file("links.txt");
foreach($urls as $url) {
echo file_get_contents($url);
}
... should have been sufficient too.
I'm trying to make ABBC3 work with PHP 7.3 and PHPBB 3.0.14 since I can't move to PHPBB 3.3 due lots of issues with MODs not ported to extensions and theme (Absolution).
I have asked help in PHPBB forum without luck because 3.0.x and 3.1.x version are not supported anymore.
So after dozens of hours trying to understand bbcode functions I'm almost ready.
My code works when there's a single bbcode in message. But doesn't works when there's more bbcode or it's mixed with texts.
So I would like to get some help to solve this part to make everything work.
In line 98 in includes/bbcode.php this function:
$message = preg_replace($preg['search'], $preg['replace'], $message);
Is returning something like this:
$message = "some text $this->Text_effect_pass('glow', 'red', 'abc') another text. $this->moderator_pass('"fernando"', 'hello!') more text"
For this message:
some text [glow=red]abc[/glow] another text.
[mod="fernando"]hello![/mod] more text
The input for preg_replace above is like this just for context:
"some text [glow=red:mkpanc3g]abc[/glow:mkpanc3g] another text. [mod="fernando":mkpanc3g]hello![/mod:mkpanc3g]"
So basically I have to split this string in valid expressions to apply eval() then concatenate everything. Like this:
$message = "some text". eval($this->Text_effect_pass('glow', 'red', 'abc');) . "another text " . eval($this->moderator_pass('"fernando"', 'hello!');). "more text"
In this specific case there's also double quotes left in '"fernando"'.
I know is not safe apply eval() to user input so I would like to make some type of preg_match and/or preg_split to get values inside of () to pass as parameter to my functions.
The functions are basically:
Text_effect_pass()
moderator_pass()
anchor_pass()
simpleTabs_pass()
I'm thinking in something like this (Please ignore errors here):
if(preg_match("/$this->Text_effect_pass/", $message)
{
then split the string and get value inside of() and remove extra single or double quotes.
after:
$textEffect = Text_effect_pass($value[0], $value[1], $value[2]);
Finally concatenate everything:
$message = $string[0] .$textEffect. $string[1];
}
if(preg_match("/$this->moderator_pass/", $message)
{
.....
}
P.S.: ABBC3 is not compatible with PHP 7.3 due usage of e modifier. I have edited everything to remove the modifier.
Here you can see it working separately:
bbcode 1
bbcode 2
Can someone give me some help please?
After long time searching for a solution for this problem I found this site that helped me build the regex.
Now I have managed to solve the problem and I have my forum fully working with PHPBB 3.14, PHP 7.3 and ABBC3.
My solution is:
// Start Text_effect_pass
$regex = "/(\\$)(this->Text_effect_pass)(\().*?(\')(,)( )(\').*?(\')(,)( )(\').*?(\'\))/is";
if (preg_match_all($regex, $message, $matches)) {
foreach ($matches[0] as $key => $func) {
$bracket = preg_split("/(\\$)(this->Text_effect_pass)/", $func);
$param = explode("', '", $bracket[1]);
$param[0] = substr($param[0], 2);
$param[2] = substr($param[2], 0, strrpos($param[2], "')"));
$effect = $this->Text_effect_pass($param[0], $param[1], $param[2]);
if ($key == 0) {
$init = $message;
} else {
$init = $mess;
}
$mess = str_replace($matches[0][$key], $effect, $init);
}
$message = $mess;
} // End Text_effect_pass
// Start moderator_pass
$regex = "/(\\$)(this->moderator_pass)(\().*?(\')(,).*?(\').*?(\'\))/is";
if (preg_match_all($regex, $message, $matches)) {
foreach ($matches[0] as $key => $func) {
$bracket = "/(\\$)(this->moderator_pass)/";
$bracket = preg_split($bracket, $func);
$param = explode("', '", $bracket[1]);
$param[0] = substr($param[0], 2);
$param[1] = substr($param[1], 0, strrpos($param[1], "')"));
$effect = $this->moderator_pass($param[0], $param[1]);
if ($key == 0) {
$init = $message;
} else {
$init = $mess;
}
$mess = str_replace($matches[0][$key], $effect, $init);
}
$message = $mess;
} // End moderator_pass
If someone is interested can find patch files and instructions here.
Best regards.
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));
I am attempting to make a (very) basic template engine for php. Based on my research I have found that a method that I am using is strongly disliked. I was wondering if anyone knew a great alternative to get the same result so I am not using it. And if anyone sees any other improvements that can be made please share!
the method that is not advised is the eval() method!
Here is the php file
<?php
class Engine {
private $vars = array();
public function assign($key, $value) {
$this->vars[$key] = $value;
}
public function render($file_name) {
$path = $file_name . '.html';
if (file_exists($path)) {
$content = file_get_contents($path);
foreach ($this->vars as $key => $value) {
$content = preg_replace('/\{' . $key . '\}/', $value, $content);
}
eval(' ?>' . $content . '<?php ');
} else {
exit('<h4>Engine Error</h4>');
}
}
}
?>
here is the index.php file
<?php
include_once 'engine.php';
$engine = new Engine;
$engine->assign('username', 'Zach');
$engine->assign('age', 21);
$engine->render('test');
?>
and here is just a test html file to display its basic function
My name is {username} and I am {age} years old!
outputs:
My name is Zach and I am 21 years old!
Many thanks in advance!
If you just want to output some text to the page, just use echo:
echo $content;
This is better than eval('?>' . $content . '<?php') for quite a few reasons: for one, if someone types in <?php phpinfo(); ?>, for example, as their username, it won't execute that code.
I would, however, note that you have some other problems. What if I do this?
$engine = new Engine;
$engine->assign('username', '{age}');
$engine->assign('age', 21);
$engine->render('test');
The {age} in the username value will be replaced with 21. Usually you don't want replacements to be replaced like that, particularly as it's order-dependent (if you assigned username later, it wouldn't happen).
I have a page test.php in which I have a list of names:
name1: 992345
name2: 332345
name3: 558645
name4: 434544
In another page test1.php?id=name2 and the result should be:
332345
I've tried this PHP code:
<?php
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTMLFile("/test.php");
$xpath = new DOMXpath($doc);
$elements = $xpath->query("//*#".$_GET["id"]."");
if (!is_null($elements)) {
foreach ($elements as $element) {
$nodes = $element->childNodes;
foreach ($nodes as $node) {
echo $node->nodeValue. "\n";
}
}
}
?>
I need to be able to change the name with GET PHP method in test1.pdp?id=name4
The result should be different now.
434544
is there another way, becose mine won't work?
Here is another way to do it.
<?php
libxml_use_internal_errors(true);
/* file function reads your text file into an array. */
$doc = file("test.php");
$id = $_GET["id"];
/* Show your array. You can remove this part after you
* are sure your text file is read correct.*/
echo "Seeking id: $id<br>";
echo "Elements:<pre>";
print_r($doc);
echo "</pre>";
/* this part is searching for the get variable. */
if (!is_null($doc)) {
foreach ($doc as $line) {
if(strpos($line,$id) !== false){
$search = $id.": ";
$replace = '';
echo str_replace($search, $replace, $line);
}
}
} else {
echo "No elements.";
}
?>
There is a completely different way to do this, using PHP combined with JavaScript (not sure if that's what you're after and if it can work with your app, but I'm going to write it). You can change your test.php to read the GET parameter (it can be POST as well, you'll see), and according to that, output only the desired value, probably from the associative array you have hard-coded in there. The JavaScript approach will be different and it would involve making a single AJAX call instead of DOM traversing using PHP.
So, in short: AJAX call to test.php, which then output the desired value based on the GET or POST parameter.
jQuery AJAX here; native JS tutorial here.
Just let me know if this won't work for your app, and I'll delete my answer.