get_declared_classes in symfony 3.4 - php

I have app in Symfony 3.4 and I need to get all classes registered in my AppBundle namespace.
I use get_declared_classes(). I've created custom namespace AppBundle\MyCustom and I keep there some classes. The problem is that symfony caches get_declared_classes() and it does not cache my custom namespace. When I use get_declared_classes() for the first time (after remove of cache files) I get all my custom classes, but I am getting a problem when I run script for next time. Any ideas?
here is repo with a problem:
https://github.com/webostin/getdeclaredclasses

The problem is that symfony caches get_declared_classes()
This is a PHP function, Symfony has no control over it.
The problem is might related to autoloading. On the 1st load, Symfony has to build the cache, so includes your class. With a warm cache this is not necessary, so your class is not autoloaded. get_declared_classes wont include your classes.
You can observe this behavior by putting $class = new MyTool(); in the 1st line of your execute method. This will trigger the autoloader, and your class will show up in declared classes.
Solution: It seems you want to get all classes implementing an interface. You can use DI for this.
Create a custom tag, and a manager class, and then use the manager class to access all tagged services in you command.
More here: http://symfony.com/doc/current/service_container/tags.html#creating-custom-tags

Related

PHP: Using a namespaced class within several other namespaces at the same time

I'm developing two WordPress plugins (exclusively for internal use) that both use the same set of PHP classes. The classes are identical except for their namespaces, and at the moment I've just copied the files from one plugin to the other, changed the namespace, and everything works fine.
Soon though I'm going to be developing more similar plugins that will also need these files, so I'd love to put them in a git submodule and just add them to any project that needs them. The problem is that multiple plugins needing them may be used on the same site, so if I move the classes to a submodule and give them their own namespace, then all of the plugins that use them would be trying to load the exact same classnames from the exact same namespace.
Is there a way to "reset" a class's namespace or re-name it somehow when it gets loaded, without editing the original file?
At the moment I have:
SUBMODULE:
namespace Submodule;
someClass {}
PLUGIN A:
namespace PluginA;
use \Submodule as PluginA_Submodule;
$classA = new PluginA_Submodule\someClass();
$classA->someMethod();
PLUGIN B:
namespace PluginB;
use \Submodule as PluginB_Submodule;
$classB = new PluginB_Submodule\someClass();
$classB->someMethod();
The site is loading, but only the class that loads first gets used -- i.e. Both plugins run someMethod() from plugin A.
Ideally what I want is for each project to use its own version of the files containing the exact same namespace and class names, and I suppose I should mention that each of the plugins are using Composer's autoloader to load them, so I had to add the Submodule namespace and the submodule directory to the autoloader array (in composer.json) and dump-autoload to get this far. This is the part that may actually be the problem, but I'm not sure it would work if I wrote my own autoloader anyway...
Given that the classes are identical I normally wouldn't worry if the plugins all use the same one, but if I make a change to the submodule I might not immediately be able to update it in every plugin on every website, and obviously it'd be a problem if an older plugin is using a newer version of the class from a different plugin.
One thought is that I could potentially not give the submodule classes any namespace at all, if there's a way for them to inherit the current namespace or something when each plugin uses them. Not sure how the autoloading would work but I could just manually load those classes if needed.
Anyway, hope this makes sense and thanks for any help.

PHP: How to extend a 3rd party vendor class downloaded with composer and load it instead of the original?

I have a library downloaded with Composer which performs several basic stuff but which has very poor class methods in some cases.
So I though to create my own class (for certain objects, not all of them) which extend the library base class and add some useful method to it.
Unfortunately I'm not very familiar with Composer and autoloader.php.
How can I achieve that? I need to create my own library and run composer?
Two choices come to my mind, you can:
Fork the entire project and change as many things as you want
Extend the classes you need, and replace declarations/injections in your src code, there's no need to modify the autoloader.

Use Composer library inside Custom Class

I'm using Doctrine DBAL to connect to my database. I created a custom class to act as a kind of Controller (it's pretty much just for retrieving data). I'm using composer's autoload to load this class, so I place it in /src/Digital/Data.php (using PSR-0). Everything works fine, but now I need to use Doctrine in /src/Digital/Data.php, do I have to put require 'vendor/autoload.php';in it? In my index file I also have this (to call the Data class). Which is the proper way to use Doctrine in my custom class?
You need to register the ClassLoader only once. The ClassLoader is registered by the vendor/autoload.php file. If you already included that file in the index file, there is no need to do that in any other file.
The best practice is to include it in the frontcontroller or bootstrap file.

Where should I add my internal classes file in symfony2?

I'm porting an old project to symfony2 in order to start learning the framework and I cannot realize how to properly add some helper functions I have in a PHP file.
Services. Wrap those function in a class (like Helper), define the class as a service and then inject it where needed (controller or another service, or even into a cli command).
The namespace (thus the path, as you tagged the question with psr-0) is up to you.

How do I use Symfony's Doctrine model classes outside of Symfony?

Is there a way to use Doctrine using the model classes I've already setup for my Symfony applications without having to call Symfony with all that overhead?
This is more to satisfy a curiosity than anything else. For all the scripts I've used, I've just been able to instantiate Symfony (which typically turns out nice since I have all of the features that I'm used to working with on this particular project. But there has to be a way to load Doctrine and use the Symfony model classes without Symfony... Right?
Doctrine isn't dependet on symfony. Doctrine is a "framework" on its own. It has it's own autoloading and can therefore work with it's classes like a regular PHP app. You can integrate Doctrine with other frameworks if you want (like CodeIgniter or Zend). So you have every freedom you need without the need to do some tedious migration of your models/data/... from one system to another.
I've come to the conclusion there really isn't a way to use the model classes from Symfony elsewhere. With a little work, you can port over the classes to a new Doctrine model (even if you use the generator, since the main model class just extends the base which extends sfDoctrineRecord (from the API docs, you can see which functions will need to be removed).
Otherwise, there isn't a practical way of doing that.
Anytime I need to access the Symfony model, I'm making a task or plugin since I do typically need part of Symfony's functionality.
As far as Symfony2 goes, just looking at the documentation makes me want to run screaming. It's not mature in any form or fashion (but, then again, neither is Symfony "legacy"). So, I'm not sure if the process would be any easier there.

Categories