I can't get my library to work. The directory structure is lib-name/src and inside theres a main dir and a tests dir, how do I tell composer to load from the /lib-name/src/main folder?
Link to my library github https://github.com/gerardorn/catalogo
There are 3 ways to map your classes for autloading with composer.
PSR-0
The recommended way is PSR-0 compatible. This protocol describes the directory structure of your library. Each namespace need to be a directory. Classes with underscores are separated as well (PEAR style).
In your case, the class Catalogable has a namespace gerardorn\catalogo. To be PSR-0 compatible the directory structure is:
- src
- main
- gerardorn
- catalogo
- Catalogable.php
In your composer.json you should put the following:
"autoload" : {
"psr-0" : {"gerardorn" : "src/main"}
}
Classmap
Alternatively you could use classmap. Classes are searched for in the directory regardless of the namespace.
"autoload": {
"classmap": ["src/main"]
}
Files
The 3th method files doesn't apply in your case.
PHPUnit
Note that PHPUnit is needed to test your library, but not to run your library. Therefor you shouldn't put that up as a required library.
It's good that you're writing unit tests. You should sign up for Travis CI. It will run your PHPUnit tests each time that you push to GitHub and warn you (by e-mail) if something got broken.
Your directory structure should be PSR-0 compatible.
i.e. your file Catalogable.php has a namespace gerardorn\catalogo, so your directory structure for this has to match the following.
- src
- main
- gerardorn
- catalogo
Related
I just upgraded to Composer 2.0 which has apparently made some modifications to how it parses classes...
composer dump-autoload -o or the alias composer du -o basically dumps a lot of lines in my console with text like:
Class MyProject\SubCategory\CoolClass located in C:/udvikling/MyProjectRoot/src/MyProjectClasses\MyProject\SubCategory\CoolClass.php does not comply with psr-4 autoloading standard. Skipping
After reading Composer psr-4 autoload issue i ensured that all names that contribute to my namespaces and classpaths are capitalized. i.e. use myproject/helperclass is now use MyProject/HelperClass
My C:/udvikling/MyProjectRoot/src/composer.json includes the following
"autoload": {
"psr-4": {
"MyProject\\": "MyProjectClasses/"
}
}
I made one go away by adding a leading backslash to the classname:
<?php
namespace \MyProject\Core;
class Timer {
//...
but... according to php.net
Fully qualified names (i.e. names starting with a backslash) are not allowed in namespace declarations, because such constructs are interpreted as relative namespace expressions.
So this seems to not be the right choice... (my IDE also gave me an angry squiggly line under it...)
Besides going back to another version of composer, how do I fix this?
File structure:
C:\udvikling\MyProjectRoot -- the root of the project
C:\udvikling\MyProjectRoot\src --the php sources
C:\udvikling\MyProjectRoot\src\MyProjectClasses -- my PHP classes
C:\udvikling\MyProjectRoot\src\vendor -- my vendor stuff for composer
C:\udvikling\MyProjectRoot\src\composer.json - my composer config
I went and did some extra reading.
Apparently one of the goals of psr-4 is to reduce the folder depth.
The “src” and “tests” directories have to include vendor and package directory names. >This is an artifact of PSR-0 compliance.
Many find this structure to be deeper and more repetitive than necessary. This proposal suggests that an additional or superseding PSR would be useful [...]
It’s difficult to implement package-oriented autoloading via an extension or amendment to PSR-0, because PSR-0 does not allow for an intercessory path between any portions of the class name.
So basically, the issue was that inside my MyProjectClasses directory, for the class MyProject\Core\Timer I had it in a similar directory structure:
C:\udvikling\MyProjectRoot\src\MyProjectClasses\MyProject\Core\Timer.php.
This had to be altered to that the base package was not included: C:\udvikling\MyProjectRoot\src\MyProjectClasses\Core\Timer.php
I have a problem with composer auto loader. Currently working on a application which was developed about 10 years back. The folder structure of 2 libraries which are currently used in the project do not comply the psr0 and psr4 auto loading rules.
The structure after the composer install looks as follows
Example 1
Folder path: /vendor/AppBook/ORS/class/model/Country
Filename: class.Country.php
PHP Class name: Country
Example 2
Folder path: /vendor/AppBook/ORS/class/model/Country
Filename: class.CountryCollection.php
PHP Class name: CountryCollection
Please advise what should I do in order that composer auto loader can detect these files.
Thank you in advance
From the docs:
You can use the classmap generation support to define autoloading for all libraries that do not follow PSR-0/4. To configure this you specify all directories or files to search for classes.
Example:
{
"autoload": {
"classmap": ["src/", "lib/", "Something.php"]
}
}
You can still add composer.json to your legacy libraries and define classmap autoloading type for them.
You can rename these files to make them compatible to PSR-4 (unlikely because that requires using namespaces - in 10 years old code?) or PSR-0. Additionally, you have to remove any explicit loading of these files via include, include_once, require or require_once because the file names changed.
PHP will autoload these classes by their class name. This will possibly run into issues if the case sensitivity in the class name is not respected everywhere. Example:
class UpperCase {}
$a = new upperCase();
The autoloading would try to find a file ending with upperCase.php, which will not match the PSR-0 required UpperCase.php, so the code will fail. However, this will work, making the situation not better:
class UpperCase {}
$b = new UpperCase();
$a = new upperCase();
The reason is that PHP treats class names case insensitive, so once a class is loaded, you can use any case in it's name. It is only the first occurrence in your code path that has to match. The problem is to be sure where this really is, so essentially it has to be correct everywhere.
Yes, the classmap feature is the easier way. But you'd still want to remove include/require calls to optimize the performance a bit, so you have to touch the code anyway. And despite it's age, it has to be maintained - so why not do it fully, switching to a well-known autoloading standard. It will help you in the long run when you have to maintain PSR-0/4 compatible classes and this old code in parallel.
I try to create my own composer library. I've chose to use psr4 for autoloading mechanism. It works fine with the library project but something goes wrong when I add this library to another project as dependency. I expect the library project create an instance of a class which is located in main project. However this class cannot be found by composer autoloader.
My library project source is here : https://github.com/brnogz/kwinsey
My example project which uses this library like that(HelloWorld class is located in controller/HelloWorld.php file) : https://gist.github.com/brnogz/e27a1dd40ba00b818b23fe7ab8815fad
Please move all your sources to a src subfolder and use "src/" as the PSR-4 target folder. Autoloading from a project root folder is pretty much undefined behaviour.
I have the following structure
application:
controllers:
- SomeController.php
- SomeOtherController.php
public:
- index.php
I am including certain packages using composer. I would like to find a way to autoload my controllers using composer. However, my controllers are not namespaced.
In cases when your project structure doesn't follow PSR-0 or PSR-4 standard, you can define a class map that could look like so:
{
"autoload": {
"classmap": ["application/controllers/"]
}
}
It will scan the given directories and files for files with .php or .inc extensions and load them.
You can read more about composer class maps here.
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/