Fog Creek Software
Discussion Board




PHP Weirdness

ok, I've got a file external to my script which contains a class definition.

I'm loading up the contents of the file with file_get_contents(), and then passing the return from that to eval().

After this, I attempt to create an instance of the class defined in the file, but I get the error "Cannot instantiate nonexistant class" or something very similiar to that.

What gives?  Is it impossible to load new class/function definitions at runtime?

I mean.. I suppose that makes sense.. but.. bummer.

muppet
Friday, July 16, 2004

Why don't you just include the file?
include_once( "file_with_class_definition" );

bah_humbug
Friday, July 16, 2004

what if I wanted to load class definitions out of the database?  Is it just impossible?

muppet
Friday, July 16, 2004

It should work -- done it before.  Also a few packages rely on that behaviour.  You must be doing something wrong..  post some code!

Almost Anonymous
Friday, July 16, 2004

function load_plugin($pluginName) {
      global $q_params;
     
      if (isset($this->loadedPlugins[$pluginName])) {
        return 1;
      }else{
        $widgetFile = $WIDGET_PATH . $pluginName . ".php";
        $codeString = file_get_contents($widgetFile);
        eval($codeString);
        $this->loadedPlugins[$pluginName] = new $pluginName ($q_params);
        return 1;
      }
    }

I pass in the name of the plugin, which in this case is "newsColumn" (and yes, I have the case of each character correct) and I get:

Fatal error: Cannot instantiate non-existent class: newscolumn in ...

One thing that jumps out at me is the case non-agreement, but that's not coming from me.  What gives?

muppet
Friday, July 16, 2004

I don't get any parse errors from eval or anything.  But one thing is weird.  During my debugging I added the line "echo $codeString" after $codeString gets assigned, and got nothing in the output at all.  But the file most definitely is not empty!

muppet
Friday, July 16, 2004

apparently I have some sort of stupid path error.  That has to be it.  But why doesn't get_file_contents throw an error?

muppet
Friday, July 16, 2004

that was it, a f*cking path error

but no error from file_get_contents for being called on a non-existant file.  That's.... yucky.

muppet
Friday, July 16, 2004

still get the "non-existant class" error even once the path issue is resolved, though.

w.t.f.

if I echo the contents of the file, I get all the code for the class def, but I can't instantiate it after calling eval.

muppet
Friday, July 16, 2004

found it

had the wrong version of the !@#$ library on the server.

after posting a hojillion times

thanks AA

muppet
Friday, July 16, 2004

nope, still doesn't work

aaaahahahahahaahaha

I'm going off to cry now.  Sorry for the 8 mile long thread.

muppet
Friday, July 16, 2004

You never did mention what the contents of the file are?

Perhaps you need to do a simple example...  create a simple file, gets its contents, instatiate the class.  If that works, make it more complex until you get what you are looking for.

Almost Anonymous
Friday, July 16, 2004

if the class definition in the file is bad, then I should get a parse error from eval()

muppet
Friday, July 16, 2004

I simplified the file, it contains:

<?php

  class newsColumn {
    var $id;
   
    function newsColumn() {
      $this->id = 1; 
    }
  }


?>

that's it, I still get "cannot instantiate nonexistant class newscolumn1".

muppet
Friday, July 16, 2004

Take out the <?php and ?> blocks..  you're evaling code remember...

eval("1+1");

Almost Anonymous
Friday, July 16, 2004

And there's a little trick if you still want those tags in there:

eval('?>'.$yourfilecontents.'<?php');

Closes the current block, write your file, and then open it again.

Almost Anonymous
Friday, July 16, 2004

no dice, same error

I'm getting ready to throw in the towel on this whole project over this. 

muppet
Friday, July 16, 2004

now I found some parse errors in the eval'ed code.  Eval wasn't throwing them, but if I feed the raw file through the php interpretter, I get uh-oh's.

I don't understand why eval didn't choke on it.

muppet
Friday, July 16, 2004

ok, not to hijack my own topic, but where is the syntax error in this:


SELECT
  S.CREATED AS STORY_CREATED,
  S.POST_SUBJECT,
  S.POST_BODY,
  S.POST_BODY_EXT,
  S.ID AS STORY_ID,
  C.*,
  U.DISPLAYNAME,
  U.ID AS USER_ID,
FROM DBF_THREAD_MESSAGES S
  INNER JOIN DBF_GRANDPARENT_OBJECTS C
    ON (S.GRANDPARENT_ID = C.ID)
  INNER JOIN DBF_USERS U
    ON (S.CREATED_BY = U.ID)
WHERE NOT (C.OBJECT_FLAGS & 0)
  AND C.OBJECT_TYPE = 'newsColumn'
ORDER BY S.CREATED DESC
LIMIT 0,5

on MySQL 4.x

I've been beating my head against this query for the past 45 minutes.  MySQL reports an error near 'FROM DBF_THREAD_MESSAGES S INNER JOIN DBF_GRAN'

I don't see it

muppet
Friday, July 16, 2004

Dude, the name of your class is Newcolumn but your trying to instanciate newscolumn1!!

"cannot instantiate nonexistant class newscolumn1"

Almost Anonymous
Friday, July 16, 2004

You need a few "AS" sprinkled around... as in:

DBF_THREAD_MESSAGES AS S

Almost Anonymous
Friday, July 16, 2004

actually.. .it was the comma after 'U.ID AS USER_ID'  :)

muppet
Friday, July 16, 2004

I hate debugging MySQL SQL statements...  the errors are not helpful enough.

Almost Anonymous
Friday, July 16, 2004

AA -

I mentioned the case sensitivity above.  The error contains 'newscolumn' but it's DEFINITELY being called as newsColumn.  The object is being instantiated now, I'm just having some trouble with the guts.

ah well.. time to troubleshoot all night.  :)

thanks for your help!

muppet
Friday, July 16, 2004

oh, and the '1' was a typo (in my post, not the code) sorry :)

muppet
Friday, July 16, 2004

No problem.  Class names in PHP are case-insensitive so (in PHP4 anyway) you'll always see classes lowercased.

Almost Anonymous
Friday, July 16, 2004

..and when such is the state of technical capacity, it is no wonder that we get angry and annoyed when they, who are not us, indulge and exhibit the very same capacity.

Stalking the trolls
Saturday, July 17, 2004

Excuse me, but where is $WIDGET_PATH declared? I do not see it declared as "global" in your function, so my best guess of what's going on is that PHP is treating it as a local variable - it's the default. No wonder you get all sorts of errors then, because unless you declare $WIDGET_PATH as global inside the function, or assign something to it inside the function, it will be treated as empty value.

One of those charming PHP disasters; one by one the two (the  implicitly declared vars and the explicitly declared globals) are just features, but when they are present in the same language combined, they become a real bug factory and debugging nightmare.

.
Saturday, July 17, 2004

yep, part of the problem was that I had to add a global declaration for WIDGET_PATH, too.  Forgot to mention that.

I'm wondering if that would still be necessary if it were defined as a const.

muppet
Saturday, July 17, 2004

oh wait.. I mean:

How spell PHP?  Please to be emailing me with response quickly.  For contract!!

muppet
Saturday, July 17, 2004

Stop stealing our livelihood, you fucking job whore, Indian free-loader!

Better?

anon-y-mous cow-ard
Saturday, July 17, 2004

You two should really consider checking in to some sort of mental clinic for your own eval() function.  Long strings of posts with only one poster is a sign that something is amiss. Also, this place is starting to look like it's inhabited by junior high students.

Clay Dowling
Sunday, July 18, 2004

*  Recent Topics

*  Fog Creek Home