eval() or evil

10 views
Skip to first unread message

PalaDolphin

unread,
Feb 6, 2010, 11:19:52 AM2/6/10
to HipHop for PHP Dev
I have to admit, when initially learning PHP, I breezed over eval()
since I wouldn't ever think of using it. After reading HipHop's ban
on eval(), I thought I might revisit the documentation at w3schools:

http://www.w3schools.com/php/func_misc_eval.asp

...only to find this horror:

"Tip: This function can be useful for storing PHP code in a database."

After I picked myself up off the floor, I thought of this evil
recommendation:

eval($_GET["code"]);

Just a little Saturday morning humor.


Sincerely,


-=- Craig A. Lance

Harald Lapp

unread,
Feb 6, 2010, 12:11:33 PM2/6/10
to HipHop for PHP Dev
i don't even understand the tip ..., how can eval be of any use for
storing php code in a "database"? w3school should provide an example
for this on their website -- i think this could be very ... errr ...
insightful ;-).

pcdinh

unread,
Feb 6, 2010, 12:16:54 PM2/6/10
to HipHop for PHP Dev
OK, no one learn to be a security expert to give you a free and
concise lesson on how to write secure PHP code. w3schools is just a
place for PHP beginners. eval() can be exploited if you use it with
untrusted user input. However, in other contexts, it can be useful
such as expression evaluation.

I think the fact that HPHP does not support eval() (yet) just say that
its implementation is not complete for general usage at the moment.
When the source is ready for release, I hope that some real experts in
PHP core team will take a close look at it.

Regards,

Dinh

Marcel Esser

unread,
Feb 6, 2010, 12:22:43 PM2/6/10
to hiphop-...@googlegroups.com
eval() will never be supported by the hiphop compiler; only by the interpreter.

It's impossible to figure out what code is in the eval statement at
compile time. Therefore, it can never be compiled.

- M.

Harald Lapp

unread,
Feb 6, 2010, 12:24:07 PM2/6/10
to HipHop for PHP Dev
i've never seen a case, where eval could not be replaced by something
else. some template engines use eval -- afaik. but i would call them
bad. it's indeed really not funny, that w3school does show beginners
such bad practice.

anyway ...

i think the problem with eval, create_function etc. regarding to
hiphop is, that eval and create_function are used to dynamically
create php code -- how should such be translated to c++?

Zachary Carter

unread,
Feb 6, 2010, 12:25:12 PM2/6/10
to hiphop-...@googlegroups.com


On Sat, Feb 6, 2010 at 12:22 PM, Marcel Esser <marcel...@gmail.com> wrote:
eval() will never be supported by the hiphop compiler; only by the interpreter.

It's impossible to figure out what code is in the eval statement at
compile time. Therefore, it can never be compiled.

- M.


Right, unless it was evaluating a simple string literal, but then you wouldn't need eval in the first place.

Craig Lance

unread,
Feb 6, 2010, 12:34:00 PM2/6/10
to hiphop-...@googlegroups.com
Well, for example: one could have a field in a database that specifies an upload folder for images as:

$_SERVER['DOCUMENT_ROOT'] . '/images/'

...which on my development server evaluates to:

C:/xampp_1.7.1/xampp/htdocs/images/

I mean you can really get creative.  But, this help HipHop, one must think in a more static way of making a C++ compiler happy.

-=- Craig
--
No trees were destroyed in the sending of this message,
however, a significant number of electrons were terribly inconvenienced.

-- unknown

Craig Lance

unread,
Feb 6, 2010, 12:38:47 PM2/6/10
to hiphop-...@googlegroups.com
The only way eval() and create_function() can be supported is with JIT support.  I don't believe HipHop target is to incorporate JIT.  I think it was the #4 reason in the slide show: to replace PHP Extensions written in C.

André Ferreira

unread,
Feb 6, 2010, 12:40:06 PM2/6/10
to HipHop for PHP Dev
I believe eval() can be supported later on if they add JIT-style
compiling to HPHP (thus eval()->JIT compile->run->proceed with program
execution).

They had mentioned that the V8 engine had some very good ideas they
could use, hopefully this is one of them. JIT can make an application
faster over time by caching the results of such compiles (Java does
this).

However I feel that eval() is mostly a really big hack, it's rare the
good developer that actually needs to use it and it brings more
problems than solutions (security concerns and scope comes to mind).

On Feb 6, 5:25 pm, Zachary Carter <zack.car...@gmail.com> wrote:

Harald Lapp

unread,
Feb 6, 2010, 12:40:55 PM2/6/10
to HipHop for PHP Dev
i see ... i think i'm not creative enough ;-)


On 6 Feb., 18:34, Craig Lance <craigala...@gmail.com> wrote:
> Well, for example: one could have a field in a database that specifies an
> upload folder for images as:
>
> $_SERVER['DOCUMENT_ROOT'] . '/images/'
>
> ...which on my development server evaluates to:
>
> C:/xampp_1.7.1/xampp/htdocs/images/
>
> I mean you can really get creative.  But, this help HipHop, one must think
> in a more static way of making a C++ compiler happy.
>
> -=- Craig
>

> On Sat, Feb 6, 2010 at 11:25 AM, Zachary Carter <zack.car...@gmail.com>wrote:

pcdinh

unread,
Feb 6, 2010, 12:44:35 PM2/6/10
to HipHop for PHP Dev
Agreed. Compiler is not the place to provide runtime lexer. FB team
already said that they bypassed Zend VM

Haiping Zhao

unread,
Feb 6, 2010, 12:45:38 PM2/6/10
to hiphop-...@googlegroups.com
When I gave the talk, it's hard for me to dive into too much details, but in
fact, HipHop does have "eval" mode one can turn on. When it's on, it will
execute the code through HPHPi on the fly. Currently, as long as you don't
have new declarations of functions and classes, it would be fine. We may be
able to actually allow new declarations of functions and classes, if we make
some more changes. Then eval can be fully supported. It will be slow for
sure. In general, eval() is bad practice. In some special situations, one
may find eval() makes some sense.

create_function('with literal string') is actually supported. That happens
when people want simple and anonymous functions on the fly for some array
walking functions. We just can't support create_function($variable) yet.

preg_replace/e can be re-written into a different way. I'll explain later
when we have the code in front of you.

-Haiping

André Ferreira

unread,
Feb 6, 2010, 12:52:09 PM2/6/10
to HipHop for PHP Dev
Preg_replace /e is the same topic as eval(), it's simply not useful
except for a handful of situations.

Honestly I don't see why go through the trouble of supporting both of
these if they simply bring bad code to the table 98% of the time.

Create_function is useful but I believe lambda functions will probably
replace it entirely once you guys get to PHP v5.3.

I'd really like if you guys could 'tone down' some of the silly things
the PHP core team did (probably due to outside pressure, namespaces
and their operator ring a big bell).

The result would be a 'stricter' language with better code ... but
that's another discussion. You're aiming for the established huge-
coded giants that probably don't feel like rewriting their stuff just
so HPHP works.

PalaDolphin

unread,
Feb 6, 2010, 1:01:52 PM2/6/10
to HipHop for PHP Dev
I believe that one of the intents of HipHop is to point the highly
optimized C++ compiler at PHP expressions at let it optimize the hell
out of that code. But, another thing mentioned in the video is that
the developers would then examine both PHP and C++ code run side-by-
side for things like the number of database calls, system calls, etc.,
to make sure they matched. Other things, like benchmarks, QA tests,
compiler anomalies, all the things you pay engineers the big bucks.
All of that human effort done ahead of release is for not if you're
going to by-pass it by inserting some JIT code pulled from a database
(or where ever) at runtime.

André Ferreira

unread,
Feb 6, 2010, 1:08:44 PM2/6/10
to HipHop for PHP Dev
If you eval() something with a JIT compile so will PHP, thus the
number of calls / io bytes / etc must be the same.

Besides, once we're at the point where we know the compiler does most
operations correctly we can start trying new things (like eval and
variable functions and etc).

As of right now, I doubt the compiler is 100% stable and that's why
they left out these 'harder' features.

A.J. Brown

unread,
Feb 6, 2010, 4:56:01 PM2/6/10
to hiphop-...@googlegroups.com
I will give you a case where eval() can't be replaced with some other code.

I have code that looks for an existing class, and if it doesn't exist, creates that class dynamically.

something likes this:

@require_once 'Some/Class.php';

if( class_exists( Some_Class, false ) ) {
   eval( 'class Some_Class extends Main_Class()' );
}
--
A.J. Brown
web | http://ajbrown.org
phone | (937) 660-3969

A.J. Brown

unread,
Feb 6, 2010, 4:58:42 PM2/6/10
to hiphop-...@googlegroups.com
I Should add, though, that ALL caching schemes require you to consider them in the architecture of an application.  In my example, I would do without that mechanism and force the end user to test for the existing class themselves in respect for HipHop.  Just like I have to adjust the architecture of other applications to make the most out of memcache.

I just wanted to defeat the idea that anything in eval() can always be directly rewritten :)

Павел Митрофанов

unread,
Feb 6, 2010, 5:26:21 PM2/6/10
to hiphop-...@googlegroups.com
On Sun, Feb 7, 2010 at 00:56, A.J. Brown <a...@ajbrown.org> wrote:
> I will give you a case where eval() can't be replaced with some other code.
> I have code that looks for an existing class, and if it doesn't exist,
> creates that class dynamically.
> something likes this:
> @require_once 'Some/Class.php';
> if( class_exists( Some_Class, false ) ) {
>    eval( 'class Some_Class extends Main_Class()' );
> }

In this case you can get around this by including a class file
dynamically. As far I know, dynamic includes are supported by HipHop.

André Ferreira

unread,
Feb 6, 2010, 5:32:09 PM2/6/10
to HipHop for PHP Dev
A.J.,

I'm not saying that eval is completely worthless, it DOES have its
uses. But they are very few (the example you mentioned is one I
guess), they're usually not vital to the application and can probably
be re-done without the use of eval. The function is used incorrectly
so much and is so slow that it feels like it's more trouble than it's
worth.

Harald Lapp

unread,
Feb 6, 2010, 5:36:26 PM2/6/10
to HipHop for PHP Dev
<?php

class a {

}

if (!class_exists('a')) {
class a {

}
}

?>

works perfectly for me ... i of course don't know, what hiphop would
make out of this ...

harald

On 6 Feb., 23:26, Павел Митрофанов <pavel.mitrofa.nov...@gmail.com>
wrote:

André Ferreira

unread,
Feb 6, 2010, 5:52:57 PM2/6/10
to HipHop for PHP Dev
HipHop will work correctly here IF the class_exists comes after the
class declaration.

What A.J. was saying is that if someone tries to call an non-existing
class, you can create it on the fly with eval() and base it off of
some parent. It will still be a class / object and hopefully, nothing
will break (thus avoiding the fatal error of class not defined).

A.J. Brown

unread,
Feb 6, 2010, 6:04:02 PM2/6/10
to hiphop-...@googlegroups.com
It would need to look like this:

if( !class_exists( $className ) ) {
       class $className {}
}


Is that valid syntax?

André Ferreira

unread,
Feb 6, 2010, 6:10:56 PM2/6/10
to HipHop for PHP Dev
No, you can't define a class' name in a class definition as a
variable.
Reply all
Reply to author
Forward
0 new messages