views:

562

answers:

4

Here's what I want to do:

$clsName = substr(md5(rand()),0,10); //generate a random name
$cls = new $clsName(); //create a new instance

function __autoload($class_name)
{
  //define that instance dynamically
}

Obviously this isn't what I'm actually doing, but basically I have unknown names for a class and based on the name, I want to generate the class with certain properties etc.

I've tried using eval() but it is giving me fits over private and $this-> references...

//edit

Ok, obviously my short and sweet "here's what I want to do" caused massive strife and consternation amongst those who may be able to provide answers. In the hope of getting an actual answer I'll be more detailed.

I have a validation framework using code hints on the site I maintain. Each function has two definitions

function DoSomething($param, $param2){
   //code
}
function DoSomething_Validate(vInteger $param, vFloat $param2){
   //return what to do if validation fails
}

I'm looking to add a validator for primary keys in my database. I don't want to create a separate class for EVERY table (203). So my plan was to do something like

function DoSomething_Validate(vPrimaryKey_Products $id){ }

Where the __autoload would generate a subclass of vPrimaryKey and set the table parameter to Products.

Happy now?

+4  A: 

This is almost certainly a bad idea.

I think your time would be better spent creating a script that would create your class definitions for you, and not trying to do it at runtime.

Something with a command-line signature like:

./generate_classes_from_db <host> <database> [tables] [output dir]
hobodave
You should at least provide a reason why.
Jordan S. Jones
No, I shouldn't. Should I provide you a reason not to beat someone to death with a hammer? No. Same thing.
hobodave
If you didn't know what death was then yes it should be explained. The OP may not understand the security issues with doing this are.
MitMaro
I'd say the security issues are besides the point. I'm sure he's trying to do something that has at least 3 better solutions.
hobodave
Valid point hobodave.
MitMaro
That is a valid point hobodave, but unfortunately it did take these comments to get that out. At any rate, your updated answer is perfect. +1.
Jordan S. Jones
Dave - I like your idea of generating the classes with a script. I should have thought of that. I know eval is evil, that's why I was asking the question... :)
Will Shaver
Great answer. +!
MitMaro
+2  A: 

Using eval() is really a bad idea. It opens a large security hole. Just don't use it!

Henrik P. Hessel
+1 for giving the reason why this is a bad idea.
MitMaro
+1  A: 

Please read everyone else answers on how this is truly a very very bad idea.

Once you understand that, here is a small demo on how you could, but should not, do this.


<?php
$clname = "TestClass";

eval("class $clname{}; \$cls = new $clname();");

var_dump($cls);
MitMaro
Yes, but when you do eval(...) this fails:eval("class $clsname{ public function DoSomething(){$this->bob = 4;}}");because you can't use "this" in the middle of a non-class function. Or if I were in a class function it would be the wrong "this" pointer...
Will Shaver
You have an escaping issue but I refuse to help any further then that because this is like everyone said a bad idea.
MitMaro
MitMaro... wow, I must have been really out of it yesterday to not notice needing to escape my $. Thanks.
Will Shaver
A: 

its funny, actually this is one of the few things where eval doesnt seem such a bad idea.

as long as you can ensure that no user input will ever enter the eval.

you still have downsides like when your using a bytecode cache that code wont be cached etc etc. but the security issues of eval are pretty much related to having user inputy in the eval, or to ending up in the wrong scope.

if you know what you are doing, eval will help you with this.

That said, in my opinion you are much better off when you no rely on type-hinting for your validation, but you have one function DoSomething_Validate($id) { // get_class($id) and other validation foo here }

foobaer