I've got some libraries loaded through composer, and I'm wondering if it's possible to add my own library in the /vendor map, and then to have the composer autoloader load it? The structure would be something like /vendor/mylibrary/ and then a namespace mylibrary.
Would this be possible? Also would it be possible to add a different map to the composer autoloader? Like for example /app/src/ and then to have it load all the classes in that folder? Or do I have to make my own loader for that?
Thanks
Reading the composer documentation:
You can even add your own code to the autoloader by adding an autoload field to composer.json.
{
"autoload": {
"psr-0": {"Acme": "src/"}
}
}
Composer will register a PSR-0 autoloader for the Acme namespace.
You define a mapping from namespaces to directories. The src directory would be in your project root, on the same level as vendor directory is. An example filename would be src/Acme/Foo.php containing an Acme\Foo class.
After adding the autoload field, you have to re-run install to
re-generate the vendor/autoload.php file.
So basically, you just need to follow PSR-0, and tell composer where to find your library, by adding that line to your composer.json
Yes.You can achieve it. Configure your composer.json file as following:
{
"autoload": {
"classmap": [ "classes" ]
}
Here classes is the name of the directory where you have all your application related classes.Vendor related class should be auto detected as well. Just add the following line to achieve both at the same time:
require 'vendor/autoload.php';
And you can use the namesapce to reference your class like the following:
use classes\Model\Article;
Yes, of course it is possible to add own libraries and you should feel highly encouraged to do so. If your library is available publicly, you can simply register it at packagist.org. If not, it's a bit more complicated, but not impossible.
If your project does not follow the PSR-0 standard, composer will create a classmap for you. A custom autoloader is not supported.
I'd recommend you to read the (really excellent) documentation about all this and come back, if you're running into problems.
http://getcomposer.org/doc/
Related
How do I autoload a set of library API functions with a composer installed library?
I have a library with a function API used to interface the libraries internal objects and want composer to automatically load the API and make it available after install without requiring the end-developer to include a file.
Currently the library is loaded by just including the __init__.php and it includes the API functions and an autoloader if required.
Thanks!
Composer always will require the end-developer to include one file, which is vendor/autoload.php. You cannot make it easier that that.
But what you can do is make including __init__.php optional because the integration of Composer allows you to use that autoloader instead. This will also work for functions, which could not really be autoloaded - Composer offers to always include a file if being told so.
So in the end your Composer configuration of that API library would look like this:
{
"name": "yourvendorname/yourfancylibraryname",
"license": "any open source identifier",
"autoload": {
"psr-0": {
"Foo_Api": "src/files"
},
"classmap": [
"extra/folders_with_any_other_class_not_conforming_to_psr0_or_psr4"
],
"files": [
"functions/file_with_your_function_definitions.php"
]
}
}
I don't know about whether your classes conform to PSR-0 or even PSR-4, but if they do, you and everyone would benefit if you can declare the autoloader with these standards. If not: Classmap will help you.
Your function definition will be loaded by the file or files mentioned in "files".
You don't need your own autoloader anymore for Composer.
Of course you could also simply mention the old __init__.php as the file to be included in "files", but this would separate your library from all the other classes, would probably be less performant (Composer already has a very good autoloader - there is no need to have two of them) and would definitely exclude all your classes from being dumped into an even faster Composer classmap autoloader.
I am trying to build a REST API using Slim PHP 2.0, Composer, and a couple third-party packages. I used Composer to install Slim by creating a composer.json file in the root of my application with the following:
{
"require": {
"slim/slim": "2.*"
}
}
After I ran composer install I have the following structure:
root/
vendor/
composer/
slim/
autoload.php
composer.json
composer.lock
index.php
I want to include the Valitron (https://packagist.org/packages/vlucas/valitron) library to do validation along with this Bcrypt (https://packagist.org/packages/openlss/func-bcrypt) library to hash passwords for users. So, I made the following additions to my composer.json file so the it looks like this:
{
"require": {
"slim/slim": "2.*",
"vlucas/valitron": "dev-master",
"openlss/func-bcrypt": "dev-master"
}
}
After I ran composer update I got the following directory structure.
root/
vendor/
composer/
openlss/
slim/
vlucas/
autoload.php
composer.json
composer.lock
index.php
From here, I am not sure how to set up the autoloading for my application. I sometimes see autoload classmap and other times see psr-0. On top of these third-party packages I am going to be creating my own models to use. One will be a base model that handles connecting to the database and then each table will have a model that I use to manipulate the said table with. So for interacting with the users table I will use my UserModel.php file below. My other question is how would I go about "using" the Valitron and BCrypt files within this one? Would I just do this:
<?php namespace Libraries;
use \Valitron;
use \BCrypt;
class UserModel extends BaseModel {
// I want to use the Valitron class here along with the crypt file
}
How would I go about setting up autoloader to accomplish this? Any help is greatly appreciated. I already dislike Composer a lot but since everyone is saying it's a must for PHP developers I am trying to force myself to learn it.
Composer provides an autoloader for third-party libraries specified in composer.json. See https://getcomposer.org/doc/01-basic-usage.md#autoloading. You can customise the autoloader for your needs, it supports both PSR-4 and classmap. See the autoload reference for more details.
I mean, it's pretty simple in reality. If you want these classes to be autoloaded, then require autoload.php
require 'vendor/autoload.php';
Or, in composer.json you can declare it.
{
"autoload": {
"psr-0": {"Libraries": "vendor/open-lss"}
}
}
Which will allow you to do:
namespace Libraries\func-bcrypt
class bCrypt_class{
}
which is what I believe you are attempting to achieve
I am wanting to structure my laravel app in a way that all of my code is under the src directory. My project structure would look something like the below. How would I do this where I can still call Route::get('accounting/item/{id}','AccountingItemController#getId')
I am wanting to avoid adding every module under src to the ClassLoader. Is there a way to tell the class loader to load all sub-directories under the parent directory src?
app
app/src
app/src/accounting
app/src/accounting/controllers
app/src/accounting/models
app/src/accounting/repos
app/src/accounting/interfaces
app/src/job
app/src/job/controllers
app/src/job/models
app/src/job/repos
app/src/job/interfaces
Yes, it's called PSR-0.
You should namespace all of your code. Typically you'll have a vendor name that you'll use a the top level namespace. Your application structure should then look something like this.
app/src/Vendor/Accounting/Controllers
app/src/Vendor/Job/Controllers
Your controllers will then be namespaced accordingly.
namespace Vendor\Accounting\Controllers;
And when using them in routes.
Route::get('accounting/item/{id}','Vendor\Accounting\Controllers\ItemController#getId');
Lastly, you can register your namespace with Composer in your composer.json.
"autoload": {
"psr-0": {
"Vendor": "app/src"
}
}
Of course, if you don't want that top level Vendor namespace you can remove it, but you'll need to register each component as PSR-0.
"autoload": {
"psr-0": {
"Accounting": "app/src",
"Job": "app/src",
}
}
Once done, run composer dump-autoload once and you should be able to add new controllers, models, libraries, etc. Just make sure the directory structure aligns with the namespacing of each file.
Do you have composer installed? You should use this:
composer dump-autoload
But you can could add directories to the Laravel's classloader. Check the reference here: http://laravel.com/api/class-Illuminate.Support.ClassLoader.html
I am using Nette Framework which uses its own autoloader. How can I define custom autoloader or just exclude the standard one from composer so I can use my own?
Alternatively, if you want an additional autoloader, you can update composer.json with:
{
"autoload": {
"files": ["src/extra/autoloader.php"]
}
}
Then run composer dump-autoload to rebuild it. Now when you include vendor/autoload.php it will also load your autoloader.
Simply don't include it if you don't want to use it. Keep in mind you'll have to handle autoloading on your own.
If your autoloader can work with it, you can use namespaces file generated by composer:
Composer provides its own autoloader. If you don't want to use that one, you can just include vendor/composer/autoload_namespaces.php, which returns an associative array mapping namespaces to directories.
Reference: Autoloading in the composer docs.
I've started a new project, where I use Composer to handle some dependencies, as well as their auto-loading.
I only keep the composer.json file in the VCS, instead of the entire vendor directory, so I don't want to start adding my code in there.
How should I handle my own project specific code, so that it auto loads as well?
This is actually very simple. Excluding vendors directory from your repository is the right approach. Your code should be stored in a separate place (like src).
Use the autoload property to make that composer recognizes your namespace(s):
{
"autoload": {
"psr-4": {
"Acme\\": "src/"
}
}
}
Assuming you have class names following the psr-4 standard, it should work. Below some example of class names and their locations on the file system:
Acme\Command\HelloCommand -> src/Command/HelloCommand.php
Acme\Form\Type\EmployeeType -> src/Form/Type/EmployeeType.php
Remember to define a namespace for each class. Here's an example of Acme\Command\HelloCommand:
<?php
namespace Acme\Command;
class HelloCommand
{
}
Don't forget to include the autoloader in your PHP controllers:
<?php
require 'vendor/autoload.php';
Read more on PSR-4 standard on PHP Framework Interoperability Group.
Note that if you edit composer.json, you need to either run install, update or dump-autoload to refresh the autoloader class paths.