In expressionengine with php parse enabled,
if i do the following, it works and i get the username displayed. logged in user is admin. So it echos out admin.
<?php
$x = '{username}';
echo $x;
?>
However if i do the following and use the{username} tag insde mkdir() function, then it doesn't work. The directory created will have the name {username} instead of admin. Why is this happening.
<?php
$x = '{username}';
mkdir($x);
?>
I'd suggest writing a quick plugin that accepts the logged-in username as a parameter, then does your mkdir() work within the plugin.
class Make_directory
{
var return_data = '';
function __construct()
{
$this->EE =& get_instance();
$username = $this->EE->TMPL->fetch_param('username', FALSE);
if($username != FALSE)
{
$dir = mkdir(escapeshellarg($username));
}
$this->return_data = $dir;
}
There's more to the plugin, but that's the guts of it. Then call it like {exp:make_directory username="{logged_in_username}"}.
Expression engine is a templating engine. It almost certainly buffers output then replaces it, which is why this will work with echo but not functions.
I'm not an expert in EE, but something like this might work:
$name = get_instance()->TMPL->fetch_param('username', '');
mkdir(escapeshellarg($name));
The point is you need to get the return of EE interpreting that, rather than just passing the raw text.
You can also use ob_start() to capture the output if you can't easily get EE's return. For example:
function mkdir_obcb($dir) {
mkdir(escapeshellarg($dir));
return '';
}
ob_start('mkdir_obcb');
echo '{username}';
ob_end_clean();
Note also my use of escapeshellarg() to reduce the risk of attack.
Is it possible you have it set up so your PHP is being parsed before the EE tags? Not only do you need to set to allow php parsing but what order it happens in as well.
http://expressionengine.com/user_guide/templates/php_templates.html
You may need to set 'PHP Parsing Stage' to 'output' in the preferences of your template in the CP Template Manager, because then PHP executes after expression engine rendered the ee tags.
Related
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;
}
I am building a website using php. I would want to separate the php from the html. Smarty engine, I guess does that, but right now its too complicated for me. Looking for a quick fix and easy to learn solution, one which is an accepted standard as well. Anyone helping please.
Consider frameworks or choose a template engine
Use a framework. Depending on your project, either a micro framework like Slim or something more complete like Laravel.
What I sometimes do when writing complex systems with quite much php code is separating it the following way (don't know your exact project, but it might work for you):
You create a php file with all the functions and variables you need. Then, you load every wepgage through the index.php file using .htaccess (so that a user actually always loads the index.php with a query string). Now, you can load the html page using file_get_contents (or similar) into a variable (I call this $body now); this variable can be modified using preg_replace.
An example: In the html file, you write {title} instead of <title>Sometext</title>
The replacement replaces {title} with the code you actually need:
$body = str_replace('{title}', $title, $body);
When all replacements are done, simply echo $body...
Just declare a lot of variables and use them in the template:
In your application:
function renderUserInformation($user)
{
$userName = $user->userName;
$userFullName = $user->fullName;
$userAge = $user->age;
include 'user.tpl.php';
}
In user.tpl.php:
User name: <?=$username?><br>
Full name: <?=userFullName?><br>
Age: <?=$userAge?>
By putting it in a function, you can limit the scope of the variables, so you won't pollute your global scope and/or accidentally overwrite existing variables.
This way, you can just 'prepare' the information needed to display and in a separate php file, all you need to do is output those variables.
Of course, if you must, you can still add more complex PHP code to the template, but try to do it as little as possible.
In the future, you might move this 'render' function to a separate class. In a way, this class is a view (a User View, in this case), and it is one step in creating a MVC structure. (But don't worry about that for now.)
Looking for a quick fix and easy to learn solution
METHOD 1 (the laziest; yet you preserve highlighting on editors like notepad++)
<?php
// my php
echo "foo";
$a = 4;
// now close the php tag -temporary-
// to render some html in the laziest of ways
?>
<!-- my html -->
<div></div>
<?php
// continue my php code
METHOD 2 (more organized; use template files, after you passed some values on it)
<?php
// my php
$var1 = "foo";
$title = "bar";
$v = array("var1"=>"foo","title"=>"bar"); // preferrable
include("template.php");
?>
template.php
<?php
// $var1, $var2 are known, also the array.
?>
<div>
<span> <?php echo $v["title"]; ?> </span>
</div>
Personally, i prefer method 2 and im using it in my own CMS which uses lots and lots of templates and arrays of data.
Another solution is of course advanced template engines like Smarty, PHPTemplate and the likes. You need a lot of time to learn them though and personally i dont like their approach (new language style)
function renderUserInformation($user)
{
$userName = $user->userName;
$userFullName = $user->fullName;
$userAge = $user->age;
include 'user.tpl.php';
}
In short, I'm building a self hosted application, and to create a basic level deterrent that'll stop those who have a small knowledge of development (i.e. my target market) from removing call backs, I've decided to use eval() and base64_decode() in order to obfuscate and execute a couple of lines of code - specifically those that deal with validating the users license key.
The problem I've run into however is that it seems that I can't run eval(base64_decode(..)); within a function.
For example, this works fine:
eval(base64_decode('c2Vzc2lvbl9uYW1lKCJfaW5zdCIpOyBzZXNzaW9uX3N0YXJ0KCk7ICRfU0VTU0lPTlsna2V5J10gPSB0cnVlOyBlY2hvICI8c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIj53aW5kb3cubG9jYXRpb24gPSAnL2luc3QvYWRtaW4vc2V0dGluZ3MnPC9zY3JpcHQ+Ijs=');
executing the following,
session_name("_inst");
session_start();
$_SESSION['key'] = true;
echo "<script type=\"text/javascript\">window.location = '/inst/admin/settings'</script>";
But this on the other hand, fails:
function escapeOut() {
eval(base64_decode('c2Vzc2lvbl9uYW1lKCJfaW5zdCIpOyBzZXNzaW9uX3N0YXJ0KCk7ICRfU0VTU0lPTlsna2V5J10gPSB0cnVlOyAkZXNjYXBlID0gICI8c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIj53aW5kb3cubG9jYXRpb24gPSAnL2luc3QvYWRtaW4vc2V0dGluZ3MnPC9zY3JpcHQ+IjsgcmV0dXJuICRlc2NhcGU7'));
}
echo escapeOut();
it should execute the following,
session_name("_inst");
session_start();
$_SESSION['key'] = true;
$escape = "<script type=\"text/javascript\">window.location = '/inst/admin/settings'</script>";
return $escape;
At first I wasn't returning $escape, but after realizing and rectifying that issue, I'm stumped. It's probably something pretty simple, but I'm pretty stumped.
Any answers as to why this doesn't work/what I can do to make it work would be greatly appreciated!
having return in your eval() statement will return from eval, not from the outer function.
i think you need something like this:
function escapeOut(){
return eval(base64_decode('c2Vzc2lvbl9uYW1lKCJfaW5zdCIpOyBzZXNzaW9uX3N0YXJ0KCk7ICRfU0VTU0lPTlsna2V5J10gPSB0cnVlOyAkZXNjYXBlID0gICI8c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIj53aW5kb3cubG9jYXRpb24gPSAnL2luc3QvYWRtaW4vc2V0dGluZ3MnPC9zY3JpcHQ+IjsgcmV0dXJuICRlc2NhcGU7'));
}
echo escapeOut();
also, keep in mind it's trivial to echo base64_decode('c2Vzc2lvbl9uYW1lKCJfaW5zdCIp...
I'm using PHP's file_get_contents in a way that makes it an API without XML. I've done this several times before, but today, it's outputting the file's ACTUAL PHP as opposed to the output HTML which is what I'm trying to get!
Here's the code:
File I'm getting, udp.php
<?php
session_start();
$user = $_SESSION['xxxxxx'];
require("connect.php");
$data = mysql_query("SELECT * FROM xxx WHERE xxx='$xx'");
$row = mysql_fetch_assoc($data);
/* Fetch Array */
$email = $row['email'];
$name = $row['firstname'].' '.$row['lastname'];
$location = $row['location'];
$dob = $row['dob'];
$gender = $row['gender'];
$dp = $row['dp'];
$joindate = $row['joindate'];
$var = $email.'####'.$name.'####'.$location.'####'.$dob.'####'.$gender.'####'.$dp.'####'.$joindate;
echo $var;
?>
And I'm using this:
<?
$getdata = file_get_contents($_SERVER['DOCUMENT_ROOT'].'/udp.php');
echo $getdata;
?>
To get the file contents from udp.php, but the problem is, I'm not getting $var, I'm getting the ACTUAL PHP! The return data is the exact PHP file contents. The actual udp.php file renders $var the way I want it to, but when getting the file, it renders the exact PHP.
That is kind of confusing to me :S
Any Ideas?
Thanks! :)
$_SERVER['DOCUMENT_ROOT'] contains a local filesystem path. The PHP interpreter is never being invoked, so you just get the file contents.
You either need to file_get_contents() it via a URL, or capture the output from include() with some buffering and store the value that way.
Use include() to get the interpreted PHP file.
That is how it's supposed to work. If you did file_get_contents on an executable file, would you expect it to execute the file and return the output? Not really.
If you want to process the PHP file and get the resulting output, use include instead.
Honestly, I think you need to read up on programming in general, and PHP specifically. What you can do to fix what you posted is to create a function in udp.php by wrapping the code in a function named something like udp_getdata() {} and then return $var; instead of echo. Then in the other code, you require_once("udp.php"); and then change: $getdata=udp_getdata(); At this point, $get_data should be set to the contents of the return value of the function udp_getdata()
That is not to say that all your code is correct, and will work, mind you. I never got that far.
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.