I'm wondering what the best way (if there is a way) for an application to auto-discover [relevant] PHP "packages" installed by Composer.
My use case specific scenario:
I have a PHP app that includes my "framework" (for lack of a better word). This framework brings some basic functionality (routing, admin etc).
I'm slowly building in more advanced functionality, say, a blog module. This module is entirely self contained in it's own directory (but obviously has dependencies on the framework).
I'd like this blog module to be a self contained Composer package, so that I can selectively require the package in my app's root composer.json file.
Now, I need for the framework to know that it's there so that it can, for example, set the routing correctly and load up any admin functionality that the module requires.
What I've thought so far:
I'm relatively experienced in PHP, but "proper" OOP and autoloading is a little bit beyond my knowledge at the moment, so please forgive if there are inbuilt functions to do this. I don't even know what terms to Google!
I have thought I could maybe read the installed.json file which composer puts at vendor/composer/installed.php but I'm not sure how to set up my packages (e.g. blog) so they announce what they are. I'd like to future proof it so that I'm not looking for known module names (or regexing vendor or package names), but rather looking for packages to say "hey framework, I know you! You can use me!"
Maybe I can somehow instruct Composer (through the package's composer.json file) to stick in an arbitrary key/value pair in installed.json?
Any suggestions welcome, or directions as to what sort of Googling I should be doing.
Oh welcome to the world of managing dependencies on your framework.
I have some experience with auraphp, where we dealt with similar issue. You can read the blog post Composer-Assisted Two-Stage Configuration .
So what we finally ended-up adding https://github.com/auraphp/Aura.Web/blob/a3870d1a16ecd3ab6c4807165ac5196384da62cd/composer.json#L26-L36 these lines in the packages that need to understand to load by the framework.
You can also see how this bundle can also get autoloaded with the configurations.
in your composer.json
https://github.com/harikt/Aura.Asset_Bundle/blob/6ea787979390e69bf6ecb1e33ce00ed90f306e2f/composer.json#L21-L27
and the config/Common.php ( https://github.com/harikt/Aura.Asset_Bundle/blob/223126cedb460e486c4f0b242719c96c14be5385/config/Common.php ) , note we have other development modes also. For a detailed look check https://github.com/auraphp/Aura.Web_Project or https://github.com/auraphp/Aura.Framework_Project
Hope that helps a bit to look into the code and work on your own solution.
Related
Thanks for your attention, this is a question of organization, I work with PHP and GIT for version control. I use Netbeans IDE to program, GIT integrated (although I am still a rookie).
Normally, I follow the approach that Symfony2 specifies for organize the project files, but I use my own framework for my projects.
The (main) question is: Any component or code part which has its own version control must be located under the /vendor/directory?
For example:
I have my project files in src\Acme\ProjectX\, also the utility package which use all my projects: src\Acme\Util\, and it is under the version control too (GIT).
and now let's remember the basic skeleton of a project based on Symfony or similar:
/app (application related elements)
/src (source code of the project)
/vendor (third party libraries)
/web (front end controller, the web directory, assets resources etc...)
So, Must be 'Acme\Util' included in the vendor directory? And, is necessary to use composer to declare the dependences?
In addition, the Utility package has a lot of classes but only few are used in projects. Must I remove those are not using by the project.
Summarizing, It will be nice if someone can contribute his knowledge for help me to represent an scenario like this.
I hope I could explained...
Thanks in advance!
Vendor directory
It's a good practice to separate external dependencies and the application code. If you are using Composer you can change it to something else.
Unused classes
Unused classes shouldn't matter if they aren't being loaded. They'll just take a bit of extra disc space.
It might be a good idea to separate the Utility package into multiple packages if you find yourself frequently using only a small part of it.
Dependency managers
It isn't necessary to use a dependency manager, but it sure does help. Having to install, configure and maintain everything manually (especially with many dependencies and sub-dependencies) would be a horror.
Our current development setup uses a single Subversion repository containing multiple projects, each with branches, tags, and trunk. We then use a "sparse checkout" to select the projects, and branches of those projects, to work with.
The result is that the directory structure of a working copy matches that of the repository, including branch information, and we never use svn switch. (This style of working will probably be familiar to anyone who uses SVN, but may be surprising to those who don't.)
We are thinking of using Composer to manage both external and internal dependencies, but I'm not sure how this can work with the sparse checkout style of working.
I would like some way of using a directory within the existing checkout to satisfy a dependency, rather than each "root project" needing a separate copy.
For example:
sites/Foo/trunk
depends on lib Aaa, so references lib/Aaa/trunk
depends on lib Bbb 1.5.*, so references lib/Bbb/branches/release-1.5
sites/Bar/trunk
depends on lib Aaa 1.0.*, so references lib/Aaa/branches/release-1.0
depends on lib Bbb 1.5.*, so references lib/Bbb/branches/release-1.5
At present, if I edit the code in lib/Bbb/branches/release-1.5, I can test those changes on both sites, without needing to commit one and update the other.
Is there any way of using Composer to manage these dependencies?
(PS: Please don't answer with "give up on SVN, use Git, it is teh awesomez"; that is an answer to a different question.)
No - I do not believe that you can do this with Composer as standard: it expects to copy the files from whichever source (Packagist/VCS/Zips) to the local vendor folder, which is not what you want.
That said, I believe there are two potential ways you could get this working (at least in part):
Autoloader
You could try using the autoload field in the composer.json file to include the correct files into the project. You would still need to manage the checkouts of the relevant branches/versions manually (like I assume you do now), but you would be able to manage the inclusion of the internal libraries through Composer. This will probably require that your libraries are properly namespaced. The paths to the files for each namespace are relative to the root of the project, but can go below the root (via the /../ path) if required.
To be honest though, if you already have an autoloader for these files, there may not be much advantage to this solution. Relevant Docs
Composer Plugin
You could also write a composer plugin/"custom installer" that could probably manage this. This would have the advantage that you could have it manage checking out the correct parts of the sparse repository to have the correct version available, as well as doing correct wildstar version checking, but would be a much more difficult and riskier venture.
The basic process would be that you would define a new package type (e.g. 'internal-svn-package'). You would create the plugin as an external library that gets installed normally via Composer, which declares (via it's composer.json) that it handles this new type of package. Your custom logic would then be used for any packages that are listed with this custom type. I'm not sure how much of the internal composer logic for SVN checkouts you would be able to reuse however. Relevant Docs
First of all, I'm a complete newbie to Composer. I've been trying it out since it's a sounds awesome and mainly because Zend Framework 2 uses it.
Zend Framework 2 is actually also the reason for this thread.
It get the basics of Composer. But with my current server setup I have a request, which I can't seem to figure out if possible.
Let me explain.
I have multiple Zend Framework 2 projects:
/home/morten/sites/Project-1/
/home/morten/sites/Project-2/
/home/morten/sites/Project-3/
All of these projects should be running ZF2. When running composer in each project - each of them get their own separate download of the ZF2 Library files. Which is a bit redundant with my setup.
I have a complete and up-to-date download of ZF2 Library located at:
/var/www/shared/Zend/
And my php.ini has that path added to PHP's include_path, so the whole ZF2 library is available for all the three projects.
IS IT POSSIBLE to make Composer use in it's setup. Because if I try to change stuff and try things out in the composer files, then it just re-downloads Zend because it's a required component for other modules.
Can this be done? And if yes, how can I do it?
Hope I have explained myself good enough for you guys to understand what I'm trying to do and want :)
Thanks a lot in advance!
Regards,
Morten
You might be able to have one composer.json file stored in /var/www/shared/Zend, where you would put your dependencies and use Composer do manage them. Then all projects could include the same autoloader.
However, I wouldn't recommend that approach:
Your project's dependencies (composer.json) should be stored with your project. If you want to install your project somewhere else (for instance if you want to move one project to another server), you are missing the composer.json to install the required dependencies.
It will not be possible to update the dependencies of one project, without updating the dependencies of all other projects. If you want to introduce a new feature in Project 1, which requires a new version of a certain dependency, all other projects will get this new version as well - which might introduce backward compatibility breaks if an older feature that Project 2 relies on, is no longer supported. Since you can only have one version of each dependency, it is not possible for two projects to have different versions of the same dependency.
This approach might be useful if all projects will have the exact same functionality and code, but in that case you should probably merge them into one project.
In all other cases, I would suggest to use Composer the way it's supposed to be used: give all projects their own composer.json file and let Composer download the dependencies per project, in each project's vendor directory. The downside is that it'll cost you a little more disk space, but you'll get a lot of flexibility for it in return.
i'm building a new project on top of CodeIgniter MVC framework, but now that i'm looking at the design, i will actually not use most of the framework features except for 1.form validation, 2.router and 3.session/cookie/input handling, and 4.views generation
even for database i will use Redbeans php ORM.
So my question
how can i glue these components that i fetched with composer from other frameworks so i can inject them into my project and be good to go without other extra stuff that i don't need ?
would it be a wise decision ? or is there any risks of depending on components rather than whole framework ?
i have googled a lot but it seems like i'm using the wrong keywords or something, i could not find any tutorial except for this one -which dictate symphony- that teach you how to do this and what are the risks of doing it
You can take a look at Packagist to explore which components Composer offers, RedBeanDB is definitely in there. However, in contrast to Symfony, CodeIgniter is not really Composer-friendly. So if you are looking for a proper way to just load these few CodeIgniter components as a dependency, I guess you're out of luck.
To keep from digressing, I'm simply going to answer your two main questions:
1) There are plenty of tutorials out there on how to use composer to grab your packages, so I wont do a full writeup, but basically what you need to do is download composer, create a composer.json file, then run composer to have it download all those packages and their dependancies. All you then need to do is in one of the already loaded codeigniter files, autoload the autoload.php file
`require 'vendor/autoload.php';`
Check the composer documentation here on how to download composer and setup your json file.
2) Definitely. The Laravel framework is actually built this way under the hood, instead of writing everything themselves, they use composer to pull in packages from other projects like Symfony to do certain tasks.
I have been making a CMS as a project for a little while now, and am currently working on the plugin management section. Instead of building my own repository & update manager, I've been toying with the idea to use composer instead. The issue is I want the admins on the site to be able to add/remove plugins at will.
So I was thinking, how bad of an idea would it be to build a front-end which runs composer? Composer is just PHP after all, it's meant to be run on production environments (granted with a composer.lock file though), and it'd resolve all of my repository, update, and dependency needs.
I knocked out a quick test script, I built and passed in a custom configuration file (instead of composer.json, the installed plugins list is stored in the database), and everything seems to be working fine. But I can't shake the feeling of this being a bad idea.
Does anyone have experience with this, and whether or not it is a good or bad idea?
Using Composer as an embedded dependency manager with a front end is actually a very valid use case for it. Here are some links with information, as well as a project meant specifically to help with embedding composer into an application.
https://github.com/dflydev/dflydev-embedded-composer
https://sculpin.io/documentation/embedded-composer
http://srcmvn.com/blog/2013/05/23/symfony-live-2013-portland-embedded-composer