php class dynamic name
Dynamically generate classes at runtime in php?
Here’s what I want to do:
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.
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
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
Where the __autoload would generate a subclass of vPrimaryKey and set the table parameter to Products.
10 Answers 10
As of PHP 7.0, with a little creativity and knowledge of some lesser known PHP features, you can absolutely do this without resorting to eval or creating script files dynamically. You just need to use anonymous classes and class_alias(), like such:
This works because anonymous classes are still assigned a name behind the scenes and put in the global scope, so you’re free to grab that class name and alias it. Check out the second comment under the anonymous classes link above for more information.
Having said that, I feel like all the people in this question who are saying «Eval is always a very bad idea. Just don’t use it ever!» are just repeating what they’ve heard from the hive mind and not thinking for themselves. Eval is in the language for a reason, and there are situations where it can be used effectively. If you’re on an older version of PHP, eval might be a good solution here.
However, they are correct in that it can open up very large security holes and you have to be careful how you use it and understand how to eliminate the risks. The important thing is, much like SQL injection, you have to sanitize any input you put in the eval statement.
For example, if your autoloader looked like this:
A hacker could do something like this:
See how this has the potential to be a security hole? Anything the hacker puts between the two bogusClass names will be run on your server by the eval statement.
How do I dynamically write a PHP object property name?
I have object properties in my code that look like this:
The problem is I have 100s of field names and need to write the property name dynamically. Otherwise, the object name and the keys for the property will always be the same. So I tried:
More or less I am trying dynamically write the php before it executes so that it can output the proper values. Thoughts on how to approach this?
5 Answers 5
Update for PHP 7.0
In cases where the (now improved) default behavior is undesired, curly braces can still be used to override it as shown below.
Original answer
Write the access like this:
This «enclose with braces» trick is useful in PHP whenever there is ambiguity due to variable variables.
I think you are looking for variable-variable type notation which, when accessing values from other arrays/objects, is best achieved using curly bracket syntax like this:
The magic method __get is you friend:
today i face that challenge. I ended up with that style of development
I worked on some code that used dynamically created object properties. I thought that using dynamically created object properties was pretty cool (true, in my opinion). However, my program took 7 seconds to run. I removed the dynamic object properties and replaced them object properties declared as part of each class (public in this case). CPU time went from over 7 seconds to 0.177 seconds. That’s pretty substantial.
It is possible that I was doing something wrong in the way I was using dynamic object properties. It is also possible that my configuration is broken in some way. Of course, I should say that I have a very plain vanilla PHP configuration on my machine.
Динамически создавать классы во время выполнения в PHP?
вот что я хочу сделать:
очевидно, это не то, что я на самом деле делаю, но в основном у меня есть неизвестные имена для класса и на основе имени я хочу создать класс с определенными свойствами и т. д.
хорошо, очевидно, мой короткий и сладкий «вот что я хочу сделать» вызвал массовую борьбу и ужас среди те, кто может дать ответы. В надежде получить реальный ответ, я буду более подробно.
у меня есть структура проверки с использованием подсказок кода на сайте, который я поддерживаю. Каждая функция имеет два определения
Я хочу добавить валидатор для первичных ключей в свою базу данных. Я не хочу создавать отдельный класс для каждой таблицы (203). Итак, мой план состоял в том, чтобы сделать что-то вроде
где _ _ autoload будет генерировать подкласс vPrimaryKey и установите параметр таблицы в Products.
8 ответов
Это почти наверняка плохая идея.
Я думаю, что ваше время лучше потратить на создание скрипта, который будет создавать свои определения классов для вас, а не пытаться сделать это во время выполнения.
что-то с подписью командной строки, например:
Это смешно, на самом деле это одна из немногих вещей, где eval не кажется такой плохой идеей.
пока вы можете гарантировать, что никакой пользовательский ввод никогда не будет входить в eval.
у вас все еще есть недостатки, как при использовании кэша байт-кода, который код не будет кэшироваться и т. д. но проблемы безопасности eval в значительной степени связаны с тем, что пользователь inputy в eval или оказался в неправильной области.
Если вы знаете, что делаете, eval поможет вам с этим.
тем не менее, на мой взгляд, вам намного лучше, когда вы не полагаетесь на тип-намек для своей проверки, но у вас есть одна функция
Я знаю, что это старый вопрос, и есть ответы, которые будут работать, но я хотел предложить несколько фрагментов, которые ответили бы на исходный вопрос, и я думаю, что предложите более расширенное решение, если кто-то окажется здесь, как я сделал при поиске ответа на эту проблему.
Создать Единый Динамический Класс
пока вы правильно избегаете текста, вы также можете добавить туда функцию.
но что если вы хотите динамически создавать классы на основе чего-то, что само по себе может быть динамическим, например, создавать класс для каждой таблицы в вашей базе данных, как упоминалось в исходном вопросе?
Создать Несколько Динамических Классов
это будет динамически создавать класс для каждой таблицы в базе данных. Для каждого класса также будет создано свойство, именуемое после каждого столбца.
Я думаю, что с помощью eval() это ненадежное решение, особенно если ваш скрипт или программное обеспечение будут распространяться на разных клиентах. Поставщики общего хостинга всегда отключают
Это может помочь создать класс во время выполнения. Он также создает methor run и метод catchall для неизвестных методов Но лучше создавать объекты во время выполнения, а не классы.
пожалуйста, прочитайте все ответы о том, как это действительно очень плохая идея.
Как только вы это поймете, вот небольшая демонстрация того, как вы могли, но не должны этого делать.
Я создал пакет, который динамически создает классы/интерфейсы/черты характера. и хранит их в файле затем вы можете просто включить созданный файл, чтобы иметь возможность использовать свой класс
Is it possible to extend a class dynamically?
I have a class which I need to use to extend different classes (up to hundreds) depending on criteria. Is there a way in PHP to extend a class by a dynamic class name?
I assume it would require a method to specify extension with instantiation.
8 Answers 8
While it’s still not possible and not exactly your answer i needed the same thing and didn’t wanted to use eval, monkey-patching etc. So i used a default class by extending it in conditions.
Of course it means if you have 100 classes to extend you need to add 100 conditions with another extending operation but for me this looked like the right way.
Yes. I like the answer with eval, but a lot of people afraid of any eval in their code, so here’s one with no eval:
It is possible to create dynamic inheritance in PHP using the power of the magic __call function. It takes a little bit of infrastructure code to work but isn’t too daunting.
Disclaimer
You really ought to think at least twice before using this technique as it’s actually kind of bad thing to do.
The only reason I’m using this technique is because I don’t want to have to either create the interface definitions or setup the dependency injections when creating templates for a site. I want to just be able to just define a couple of function ‘blocks’ in a template and then have inheritance automatically use the correct ‘block’.
Implementation
The steps required are:
The child class now extends a ‘DynamicExtender’ class. This class intercepts any calls made by the child class, to methods that don’t exist in the child class and redirects them to the parent instance.
Each ‘ParentClass’ is extended to a ‘ProxyParentClass’. For every accessible method in the parent class, there exists an equivalent method in the ‘ProxyParentClass’. Each of those methods in the ‘ProxyParentClass’ checks to see if the method exists in the ChildClass and calls the childs version of the function if it exists, otherwise it calls the version from ParentClass
When the DynamicExtender class is constructed you pass in what parent class you require, the DynamicExtender creates a new instance of that class, and sets itself as the child of the ParentClass.
So, now when we create the child object we can specify the parent class required and the DynamicExtender will create it for us, and it will appear as if the child class is extended from the class we requested at run-time rather than it being hard-coded.
This may be easier to understand as a couple of images:
Fixed inheritance is fixed
Dynamic inheritance with proxies
Demo implementation
The code for this solution is available on Github and a slightly fuller explanation of how this can be used here, but the code for the above image is:
PHP Class name with variable name and namespace
I´m using PHP5 to build my own MVC framework. I have a situation where all of my controllers are in the Controller namespace, as:
At the application logic I need to choose wich controller to call from the URL passed from the call, as follows:
On the other way, If I remove the namespace from the controller and call:
Please do not suggest changing the first letter to uppercase as I may have classes like CustomerReceipt, PersonalCashWithdrawl, etc..
Thanks for helping.
2 Answers 2
What you could do is create an array that would match files with classes.
For instance, if your folder contains:
The associative array would contain:
By building that kind of array, you can match a class (no matter its case) to a file.
Recipe for a disaster
Another thing you want to consider is that classes in PHP are case insensitive. That is why namespaces are important. That means that the following code works perfectly:
Suggested solution
I really do think you should match the class name case to the file. That way, you will avoid potential conflicts and make sure you do not wrongly map a class to the wrong file.
I am not advising you to change the first letter to uppercase, I am suggesting that you strictly use the case provided by the class to find the correct path.
The developer should know: if you type the class name incorrectly (meaning without respecting the case), you can’t expect the autoloader to work correctly.
Routing
Most frameworks can do auto-routing but also offer the possibility to do manual routing. You could add a routing module that will allow developers to «overwrite» the default routes. By doing that, you will please those who want to respect your standards and those who want to do it their way.
Conclusion
Your questions seem to be simple. But, in fact, there are so many things you will have to consider if you want it to be flexible and avoid being strict.
You could also mix the strategies provided in this answer like this: