How to parse file without using eval - PHP? - php

Is there any other way to parse the file without eval()? I'm trying to render the php code without using php tags inside index.gs and so far i can do it only with eval(). The problem is not only to parse vars, but custom template characters.
here is the sample of code below.
$render = file_get_contents($this->file);
$render = $this->parse_extends($render);
$render = $this->parse_assets($render);
$render = $this->parse_vars($render);
$render = $this->parse_vars_skip($render);
try {
ob_start();
eval('?>' . $render);
$render = ob_get_contents();
} finally {
ob_get_clean();
}
return $render;
The return $render - return to View::class code for response

If the allow_url_include directive is enabled in php.ini, then it’s possible to execute this code using
include "data://text/plain;base64," . base64_encode($render);
but this setting is disabled by default, and cannot be changed within user code, but only through editing the php.ini file; so unless explicitly enabled in php.ini (and there normally isn’t any good reason why it should be), then it isn’t really an option.
An alternative is to create a temporary file, write the code there, and then execute it using include:
$tempFilename = tempnam("/tmp", "MyTemplate");
file_put_contents($tempFilename, $render);
include $tempFilename;
unlink($tempFilename);
But both have similar issues and dangers to eval().

Related

Cache dynamic JavaScript generated by PHP

I use JShrink with a custom function to combine 8 uncompressed JavaScript files to a single compressed (minified) one, like this:
<?php
// Filename: js.php
header('Content-type: text/javascript');
require_once '../JShrink.php';
function concatenateFiles($files)
{
$buffer = '';
foreach($files as $file) {
$buffer .= file_get_contents(__DIR__ . '/' . $file);
}
return $buffer;
}
$js = concatenateFiles([
'core.min.js',
'promise.js',
'welcome.js',
'imagesloaded.js',
'cropper.js',
'translate.js',
'custom.js',
'masonry.js',
]);
$output = \JShrink\Minifier::minify($js);
echo $output;
Then I call this php file in my index page footer:
<script type="text/javascript" src="<? echo $url ?>/js/js.php"></script>
It is not being cached.
I modify my JS codes daily and I don't like to keep combining them manually, but also I need a way to get the echoed JS code cached, only that code and not all php files on the server.
How can I do this, and how would the cache purge process be?
Thanks in advance.
In theory, you need to use a header("...") with proper expiration. In practice, that's not working properly. You can spend your life googling for proper examples of "Cache-Control" and "Expires:" and none of what you find will work. So I suggest you to read this:
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching
ETags are the modern solution to tell the browser when your resource has changed - or not.
If the cache file doesnt exist or if any of the file modification timestamps is later then the cache, render it, then safe it to the cache, then echo the cache or the rendered result.

CodeIgniter with PHPABTest

I'm building a CodeIgniter site, and attempting to use php ABTest in the controller.
I saved the phpabtest.php file as phpabtest_helper.php in the "helpers" folder, and loaded it in the controller. It's initialized in the PHP logic as such:
public function view($name)
{
$this->load->helper('phpab');
$testpopup = new phpab('test_popup');
$testpopup->add_variation("popup");
$type = $this->Types->getTypeBySlug($name);
$data['type'] = $type;
$data['items'] = $this->Items->getItemsByType($type->id);
$alltypes = $this->Types->getAll();
$headerdata['alltypes'] = $alltypes;
$headerdata['current'] = $type->id;
$this->load->view('header');
$this->load->view('typeheader', $headerdata);
if($testpopup->get_user_segment()=='popup'){
$this->load->view('type_new', $data);
} else{
$this->load->view('type', $data);
}
$this->load->view('footer');
}
It works fine on my localhost, but when I upload it to the server, it breaks, just displaying a blank page. I've isolated the problem to the initialization of the new phpab object. In the helper, it does ob_start(array($this, 'execute')); and this line seems to be what is breaking the code.
What server settings should I be looking at to get it to work? I'm assuming it's a server setting issue because it works fine on my localhost. If I'm wrong and it's some other issue, how do I fix this?
You might want to check your PHP settings. You'll find a setting called output_buffer in your php.ini file that might be set to Off.
Exert from php.ini:
; Output buffering allows you to send header lines (including cookies) even
; after you send body content, at the price of slowing PHP's output layer a
; bit. You can enable output buffering during runtime by calling the output
; buffering functions. You can also enable output buffering for all files by
; setting this directive to On. If you wish to limit the size of the buffer
; to a certain size - you can use a maximum number of bytes instead of 'On', as
; a value for this directive (e.g., output_buffering=4096).
output_buffering = 4096

Handling Reading/Writing Files in PHP?

It's been a while since I've touched PHP, and I've been working in C# for a while. I need to do some file reading/writing, but I'm not sure where to start. I've been spoiled by Visual Studio's code-completion and real-time error checking, and it's a bit difficult going over to such a weakly-typed language.
In PHP, what's returned when reading a file, and what needs to be written when writing?
I need to work with the file in hex, but decimal would be fine too. Is there any way to read it in any way but a string?
There is a several ways to read and write files:
You can create a handler by fopen() function.
The other way is just file_get_contents(), this function just returns content. And file_put_contents() just put any data to file.
As example of the handler, here is a logging stuff:
if (!is_writable($this->file) && $name !== self::CORE_LOG)
{
self::getInstance(self::CORE_LOG)->log(sprintf('Couldn\'t write to file %s. Please, check file credentials.', $name));
}
else
{
$this->handler = fopen($this->file, 'a+');
self::$instances[$name] = &$this;
}
...
if ($this->handler)
fwrite($this->handler, '[' . date('r') . '] : ' . $l . "\n");
...
if ($this->handler)
fclose($this->handler);
Here you can read about and Filesystem managment functions

PHP files with 'cmt' extension (?)

This might sound a bit silly.
I have to update a website with a new interface, and although I received the old code I am lost. (As far as I know, I received the complete website, phpPgAdmin included)
Most of the files are .cmt but I'm pretty sure it's PHP, index.cmt for instance is
<?
include_once('redirected.php');
exit();
function get_lang_from_ip() {
$client_ip = $_SERVER['REMOTE_ADDR'];
$client_hostname = gethostbyaddr($client_ip);
if ($client_ip != $client_hostname) {
$dom_arr = split('\.',$client_hostname);
$lang_id = ($dom_arr[sizeof($dom_arr)-1] == 'hu') ? 'hu' : 'en';
} else {
$lang_id = 'hu';
}
return $lang_id;
}
function set_target() {
$valid_lang_arr = array('hu', 'en');
if (isset($_GET['lang_id']) && in_array($_GET['lang_id'], $valid_lang_arr)) {
$lang_id = $_GET['lang_id'];
} elseif (isset($_COOKIE['lang_id']) && in_array($_COOKIE['lang_id'], $valid_lang_arr)) {
$lang_id = $_COOKIE['lang_id'];
} else {
$lang_id = 'hu'; //get_lang_from_ip();
}
setcookie('lang_id', $lang_id, time()+3600*24*365, '/');
return $lang_id;
}
header('Connection: close');
header('Location: /'.set_target().'/');
?>
The .php files however don't begin with the <? short opening tag, but with <?php instead. And most importantly, the .cmt files are not parsed, if I navigate to the index.cmt I see the code in the browser, and thus I can't even put the old layout back together.
Any help is appreciated.
You can make a .htaccess file, and include the following:
AddType application/x-httpd-php .cmt
That should allow PHP to be executed on .cmt file extensions.
Please note that this fix can only be used on Apache web servers or others that support .htaccess.
Although, if possible, I'd recommend that you change all .cmt file extensions to their appropriate counter part, .php.
While #Josh Foskett has a valid answer, I think an actual solution would be to go through your files and rename the .cmt extensions to .php for scalability and to avoid confusion down the road.
Consider "phasing out" the legacy extensions by bringing them up to the current extension standard. Make this a project, not a quick fix, and I think you'll be much happier with your code base.
Enable short_open_tag in php.ini.
This will make sure, that php is actually executed, if it's included from an other file. It still won't execute, .cmt files directly, but if you have main .php entry files, that's exactly the behaviour you need.
You need to configure your server to parse .cmt files as PHP.
Also, both <? and <?php are valid opening tags for PHP, though the short version might be turned off in PHP settings (usually define in php.ini somewhere in the filesystem).

PHP 'copy' not working

Can anybody tell me why this function isn't copying the file at all?
$pluginfile = get_bloginfo('template_url') . '/wp-content/plugins/supersqueeze/supersqueeze.php';
$urlparts = get_bloginfo('template_url');
$homeurl = home_url();
$urlstrip = str_replace($homeurl, '..', $urlparts);
$urldest = $urlstrip . '/supersqueeze.php';
function copyemz(){
global $pluginfile; global $urldest;
if(!#copy($pluginfile,$urldest)) {
$errors= error_get_last();
}
}
This file is run from /public_html/wp-admin/plugins.php
I need it to copy the file at ($pluginfile) /public_html/wp-content/plugins/supersqueeze/supersqueeze.php
to ($urldest) /public_html/wp-content/themes/[active wordpress theme] - of course replacing [active wordpress theme] with the directory of the theme.
You need to ensure that you have write permissions to /public_html/wp-content/themes/[active wordpress theme] as well as any other files you may be overwriting.
So, the second parameter to copy() must be a local file. Make sure it is also a writable destination (chmod) like webbiedave said.
$desturl = "./supersqueeze.php";
The reason is two-fold. PHPs http stream wrappers don't support POSTing or PUTing files, which a write-to action would require. Second, your webserver probably wouldn't support HTTP PUT either. (Though a small requesthandler script could handle such.)

Categories