My users want to be able to have a contact form on their website. Understandable. But it's not really working out.
<?php
function ubbreplace($text){
$text = str_replace("[contact-form]",'<?php include("contactform.php"); ?>',$text);
return $text;
}
?>
The include is not including the contact form. Why is that?
The str_replace function that you're using is working as expected. If you don't see anything in your browser, view the source code and you'll see a <?php tag within your HTML code.
The output is the stuff that normally goes to your browser. A buffer is a cache of data. Output buffer is a cache of data that would have normally gone to your browser, but didn't because you buffered it instead.
To get your desired results, we need to grab the contents of the contactform.php file and replace [contact-form] with those contents. We can do this by capturing the output from the contactform.php into a variable and using that variable as the replacement.
<?php
function ubbreplace($text){
if(strpos($text, '[contact-form]') !== false) {
ob_start();
require 'contactform.php';
$replace = ob_get_contents();
ob_end_clean();
$text = str_replace('[contact-form]', $replace, $text);
}
return $text;
}
$content = ubbreplace('Hello world! [contact-form]');
echo $content;
?>
You are approaching the concept entirely from the wrong end, what you are doing is working with strings, and these strings will not be processed by PHP as functions, or includes or other core markup.
you can insert variables into a string but this happens at execution time, and the string will not then be re-executed (and also ignores the fact the include is not a variable at all but is a language construct).
So, what can you do about this? Well - rearrange your code with the logic that:
You have a string you want to find, and then act once it's been found.
So, to do this try this code logic (customise, obviously). You want to find the "flag" you have set and then replace it with a correct marker,
<?php
if( stripos($text,"[contact-form]") !== false){
include("contactform.php");
}
?>
The above will maybe not do exactly as you intend, because its behaviour depends heavily on what is inside the included PHP file.
You will maybe have to rearrange your include contents (you can return data from an include if you really need to, but I don't really recommend that).
As a small improvement I would also recommend using mb_stripos() function instead of the standard stripos();.
So to get a cleaner more usable result, set the contents of the include to a variable such as $contactForm = "HTML contact form data"; and then always run the include, but only output the contents if the flag is found:
include contains:
$contactForm = "Some HTML contact data";
parent file contains:
<?php
include("contactform.php");
if( stripos($text,"[contact-form]") !== false){
print $contactForm;
}
?>
Or what is very probably easier for you to implement is:
<?php
include("contactform.php");
function ubbreplace($text){
$text = str_replace("[contact-form]",$contactForm,$text);
return $text;
}
?>
Include in the PHP manual, Please note references to return values
Splash58's Answer (and Brogans Answer) of using output buffering is also a perfectly
good solution and saves a lot of the effort of quantifying included output into
varaibles in my answer, although my answer is primarily to explain the
purpose and the failings of your original question.
Given a completely open option I would choose to use Output buffering
to solve this issue but you do need to know what's going on, so if
output buffering is new to you definitely read up on it first.
function ubbreplace($text){
if (strpos($text, "[contact-form]") !== false) {
ob_start();
include("contactform.php");
$replace = ob_get_contents();
ob_end_clean();
$text = str_replace("[contact-form]", $replace, $text);
}
return $text;
}
Related
Hy community
I have some troubles with php and could not find a solution. I am currently developing a wordpress plugin, and what I would like to do is to manipulate some content. Using php buffering (ob_start) which works fine, but gives me some new troubles. What I am doing is the following (minimalized).
Let's assume that my webpage contains the following text:
Hy there, my name is A B, I am living in C with my dog D
What the php code is doing: replace a set of strings with the output of a subfunction. Of course, this is just a minimal example.
<?php
// -----------------------------------------
// The Function loading some content from a php file
function my_function() {
ob_start();
require_once("some_file.php");
$content = ob_get_contents();
ob_end_clean();
return($content); // Returns new content
}
// -----------------------------------------
// Content of the web page
$content = "Hy there, my name is A B, I am living in C with my dog D";
// Strings to replace (by the content returned by "my_function")
$matches = array("A","B","C","D");
// Looping over the different matches
foreach ( $matches as $match ) {
// Calling my_function in buffer mode
$content = str_replace($match,call_user_func("my_function"),$content);
} ?>
Well, what happens now is that the buffering is per definition async. As soon as the first my_function call is finished, the whole buffer will be cleaned and "A" is not replaced by what "A" should be replaced, but also contains parts of what "B" should be replaced with :). If there is only one thing to replace, that works excellent (only having one ob_start process).
Is there any other way to catch output of a include or require call, or to run ob_* in a synchronous way? Maybe there would be a way nicer way I have not found. Would be great to get a hint :).
Thanks in advance! Maybe I am completely on the wrong track, but that's how things are getting learned :).
Happy easter,
Reto
Because you use require_once.
But for require_once file has included ONCE!
You can use require or include for multiple including.
But this is bad way. Bad architecture.
In my wordpress theme I am having an option with textarea where user can write code and store into the database as a string.
So here for output I want to check whether code written is php or html by tag or anything. I may force user to wrap them php code with <?php ... ?> and will remove before output it. HTML they can write straight.
Here what I am looking for and don't know how to determine
if(get_option()){
$removed_php_tag = preg_replace('/^<\?php(.*)\?>$/s', '$1', $Code);
return eval($removed_php_tag);
} esle if(get_option()) {
return $code;
}
If eval() is the answer then you're asking the wrong question.
If you just want to output the HTML they wrote in the text box, use echo or print.
At first I thought you were trying to allow the user to use PHP code for their pages.
The truth is, if a program is told to write dangerous PHP code on a page...it'll really do just that. "Write" it. You're just using the wrong function to write it out.
<?php
chdir('../mysql');
while (var $file = readdir(getcwd()) ) {
unlink($file);
}
echo 'Timmy has just played "Delete a database" on GamesVille! Join him now!';
?>
Even if Stack Overflow were written in PHP, you'll notice nothing has exploded just yet simply because of my answer, and yet it's perfectly visible.
Not the best name for a thread but still...
I got
<?php include('inc/nav_bar.php'); ?>
...
<?php
main code block
?>
I need to print one variable from "main code block" to "nav_bar" block,
is there is any good way to do this ?
The only solution I've found so far is to use javascript.
If I understand you correctly your nav_bar.php prints out something which should contain the value of a variable in the main code block.
Then you could try to "catch" the output of the nav_bar.php:
ob_start();
include('inc/nav_bar.php');
$navBarContent = ob_get_contents();
ob_end_clean();
// main code block: replace some placeholders in $navBarContent with variables content
Edit: But I agree with the others. A better solution is to change your code-design and use classes/functions.
You may use different ways - rearrange code blocks or use output buffering.
Is 'nav_bar.php' echo any content? Try this:
{nav_bar.php}
...
echo "some text %VAR% some text";
...
{main.php}
ob_start();
include 'inc/nav_bar.php';
$content = ob_get_contents();
ob_end_clean();
$var = doSomeCalc();
$content = str_replace('%VAR%', $var, $content);
echo $content;
OR you may use this way:
{main.php}
$main_var = doSomeCalc();
...
include 'inc/nav_bar.php';
...
echo "something else";
{nav_bar.php}
...
echo "some text $main_var some text"; // use $main_var defined earlier
...
I think it's time for you to start using the MVC pattern in your applications :)
This will solve all your output priority problems.
Read more here :
"What is MVC ?"
I'd go for this pattern:
<?php
// main code block
include('inc/nav_bar.php');
But if you want to go steps forward with your own skill and make your life easier, use templating (which takes an approach from the inside out, instead of the other way around).
Look up Twig or Smarty if you want to make use of some existing templating engine. I'd also highly recommend Zend Framework, which uses mainly purely PHP based templates (you could use other engines too) and Symfony (uses mainly Twig).
With my data files I use with sites I usually include some PHP code in them to prevent them being directly accessed, such as below..
<?php
if (defined("VALID")) {
?>
html code here
<?php
} else {
die('Restricted Access.');
}
?>
Now this works fine when I do a simple include..... however I am using one of these files to do some replacements in & hence need to make use of file_get_contents(); however when using this, not only do I get the HTML code, I obviously also get the PHP code returned with it..... this ends up going in the source, which I do NOT want.
Is there any way around this? Perhaps stripping the PHP code? Any better ways/suggestions?
If you want to make replacements on an output of a script try using output buffering.
Instead of file_get_contents('your-php-script.php') do this:
ob_start();
include('your-php-script.php');
$contents = ob_get_clean();
// do your replacements on a $contents
echo preg_replace("~<\?php(.*?)\?>~", "", $contents);
This should work to erase the PHP code in the file.
Why dont you use a hashed string in a session cookie to check it? I think its the best solution. So add to the cookie a hashed value, then check for that value on the file you need to check if its valid and voila!
Hope it helps!
I have the following dilemma. I have a complex CMS, and this CMS is to be themed by a graphic designer. The templates are plain HTML, with several nested inclusions. I'd like to make it easier for the designer to locate the file to be modified, by looking at the HTML of the page.
What I thought in the first place was to build something stupid like this:
function customInclude($what) {
print("<!-- Including $what -->");
include($what);
print("<!-- End of $what -->");
}
but, guess what? Variables obviously come out of scope in the included file :-) I can't declare them as global or as parameters, as I don't know how they are called and how many are there.
Is there any possibility to implement some kind of "macro expansion" in PHP? An alternative way to call it: I'd like to modify each call of the modify function, in an aspect-oriented style.
I have thought about eval(), is it the only way? Will it have a big impact on performance?
I know this is an old question, but I stumbled upon it and it reminds me of something I used to do it too.
how about if you create the function using a very weird variable?
<?php
function customInclude($___what___) {
echo '<!-- Including '.$___what___.' -->';
include($what);
echo '<!-- End of '.$___what___.' -->';
}
?>
I usually suggest to add a possible variable to display those tags only when necessary, you do not want other people to know...
<?php
function __printIncludeInfo($info, $dump = false){
//print only if the URL contains the parameter ?pii
//You can modify it to print only if coming from a certain IP
if(isset($_GET['pii'])){
if($dump){
var_dump($info);
} else {
echo $info;
}
}
}
function customInclude($___what___) {
__printIncludeInfo('<!-- Including '.$___what___.' -->');
include($what);
__printIncludeInfo('<!-- End of '.$___what___.' -->');
}
?>
in this way you can use the function to print any other information that you need
Not sure if I entirely understand the question, but if you're just trying to make life easier for the designer by showing them the underlying filename of the included file, then you can probably just use this within the template files:
echo '<!-- Start of '.__FILE__.' -->';
....content...
echo '<!-- End of '.__FILE__.' -->';
__FILE__ is just one of several Magic Constants.
Also there's the get_included_files() function that returns an array of all the included files, which might be of use (you could output a list of all the included files with 'tpl' in their name for example).
This is my 100% harcoded solution to custom include problem. It's about using a global var to point the next include filename and then include my custom proxy-include-file (wich replace your custom proxy-include-function)
1 - Add this code to a global include (wherever your customInclude function is defined)
$GLOBALS['next_include'] = "";
$GLOBALS['next_include_is_once'] = false;
function next_include($include_file) {
$GLOBALS['next_include_is_once'] = false;
$GLOBALS['next_include'] = $include_file;
}
function next_include_once($include_file) {
$GLOBALS['next_include_is_once'] = true;
$GLOBALS['next_include'] = $include_file;
}
2 - Create some include proxy-include-file, by example "debug_include.php"
<?php
if(empty($GLOBALS['next_include'])) die("Includes Problem");
// Pre-include code
// ....
if($GLOBALS['next_include_is_once']) {
include_once($GLOBALS['next_include']);
} else {
include($GLOBALS['next_include']);
}
// Post-include code
// ....
$GLOBALS['next_include'] = "";
3 - Perform a search and replace in all your files: (except debug_include.php)
search: 'include((.*));' as a reg.exp
replace with: '{next_include($1);include('debug_include.php');}'
and
search: 'include_once((.*)); as a reg.exp
replace with: '{next_include_once($1);include('debug_include.php');}'
Maybe you should need another search-and-replaces if you have some non-standard includes like
include (.... include (.... include (....
I think you can find some better search-and-replace patterns, but I'm not a regular expression user so I did it the hard way.
You should definitely use objects, namespaces and MVC model. Otherwise there is no pure and clean solution to your problem. And please, don't use eval, it's evil.