The following problem: I have defined a classmap in my composer.json:
"autoload": {
"classmap": [
"app/controllers",
"app/models",
"app/helper.php"
]
}
However, when I create a new file in the "controllers" or "models" folder, it will not load them and I always have to make a composer dump-autoload.
Is this the correct behavior? I thought the autoloader from composer monitors the folder for new files then?
Yes, this is correct behaviour. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.
Generating the classmap requires Composer to know the filename that contains a certain class. This can only be done by parsing the whole source code in the directory and scanning for classes, interfaces and trait definitions.
This usually is a CPU and I/O intensive task, so it is only done when Composer does install/update or (on demand) dumps the autoloader, it is not done with every require "vendor/autoload.php";.
Note that the classmap autoloading is simply there for old legacy codebases that didn't implement at least PSR-0. It is not intended for new code - unless you want to pay the price to dump the autoloader again and again during development.
Go to the root of your server by SSH. Now do the following:
Run ls to list all the files.
You will see composer.lock file; remove the file with rm composer.lock command.
Now run php composer update command.
Depending on your linux type you may have to run php-cli composer update.
Step 3 will create a new composer.lock file and all your classes will be loaded again. Do this anytime you add new classes.
or:
Run composer dump-autoload command.
As already pointed out this is correct behavior. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.
The classmap autoload type specified is composer.json is mainly used by legacy projects that do not follow PSR-0 or PSR-4. I have recently started working on such a project and wanted to try to automatically run the composer dump-autoload command when a new class is created. This is actually tricky without including all of the composer source inside the project. I came up with this just to remind the developer they need to dump the classmap:
$loader = include_once 'vendor/autoload.php';
if ( ! $loader ) {
throw new Exception( 'vendor/autoload.php missing please run `composer install`' );
}
spl_autoload_register(
function ( $class ) {
if ( 'A_Common_Class_Prefix' === substr( $class, 0, 10 ) ) {
throw new Error( 'Class "' . $class . '"" not found please run `composer dump-autoload`' );
}
},
true
);
This registers another autoloader which is run after composer's autoloader so any classes composer did not find would be passed to it. If the class matches a prefix an exception is throw reminding the developer to re-dump the autoloader and update the classmap.
For me, it somehow did not work too with Yii 1 class-map, when I added - required it along with many other libraries present - I don't remember exactly perhaps I manually edited the file or file permissions were to blame, it was not regenerated for some reason, even when I removed the composer.lock and erased completely the vendor folder - perhaps some cache, as far as I remember, but effectively what helped was to install firstly isolatedly only this single library, it generated class-map, then I added all the other remaining libraries separately at once at second step, viola, everything loadable.
Related
I've renamed my app folder to aplicativo and changed the namespace to aplicativo. Everything works but artisan make commands.
I changed namespace through composer.json
"psr-4": {
"aplicativo\\": "aplicativo/",
}
Plus command:
artisan app:name aplicativo
You won't get this to work. You can rename the namespace (as you did with the command), but you can't rename the directory because it's hardcoded as app.
You can see the source here.
Then... if your using composer try this command
composer dump-autoload
The good news is that Laravel has now added support for custom App path. You can override the App path by adding the following code in bootstrap/app.php (or provider).
/*...*/
$app = new Illuminate\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
// override the app path since we move the app folder to somewhere else
$app->useAppPath($app->basePath('src'));
Similarly, you can change other paths (database, language, storage, etc.). You can find all the available methods here.
I have two different systems with a git repository cloned on them.
the project uses composer to install various dependencies.
One of these is pear/HTTP_Request2 which requires Net/URL2.
Both systems are Windows with a xampp development enviroment. So both run an Apache2 with a PHP 7.1.* installation.
On one of them everything works perfectly after installing via composer install. But the other one always Errors in the autoloaded HTTP/Request2 code:
<b>Warning</b>: require_once(Net/URL2.php): failed to open stream: No such file or directory in <b>C:\xampp\htdocs\XXX\vendor\pear\http_request2\HTTP\Request2.php</b> on line <b>25</b><br />
<br />
<b>Fatal error</b>: require_once(): Failed opening required 'Net/URL2.php' (include_path='C:\xampp\htdocs\XXX\vendor/pear/pear_exception;C:\xampp\htdocs\XXX\vendor/pear/http_request2;C:\xampp\php\PEAR') in <b>C:\xampp\htdocs\XXX\vendor\pear\http_request2\HTTP\Request2.php</b> on line <b>25</b><br />
Looking at the code in the Package we find:
if (!class_exists('Net_URL2', true)) {
require_once 'Net/URL2.php';
}
The dependency of NetURL2 was successfully installed, judging by composers output.
None the less I tried to fix it by also requiring the dependency from HTTP/Request2 "pear/net_url2" : "^2.2.0", in the Project after i heard from a bug (long closed but still) about problems with that (Issue#composer git), which didn't result in a change.
Judging by the inspected code I also assume this question is outdated.
Now I'm stuck not knowing what to do next... Help?
Edit:
My composer.json essentially looks like this if anyone was wondering:
{
"require":
{
"php":">=7.1.4",
"pear/http_request2": "v2.3.0",
"ext-json":"1.5.0",
"ext-PDO":"7.*",
"ext-pdo_mysql":"7.*",
"ext-mbstring":"7.*",
"ext-gd":"7.*"
},
"autoload": {
"files": [
"helper.php",
"settings.php"
],
"classmap": ["./"],
"exclude-from-classmap": ["vendor/"]
}
}
To troubleshoot Composer in general, you can add -vvv flags for verbose information.
Secondly, when you've XDebug extension for PHP installed, you will see a Call Stack each time when a Fatal error happens.
Note: Run phpenmod -s cli xdebug to enable XDebug in CLI mode.
The fatal error happens in pear/http_request2 package (as per vendor/pear/http_request2/HTTP/Request2.php) when it tries to include Net/URL2.php file (part of pear/net_url2, full path: vendor/pear/net_url2/Net/URL2.php).
This path should normally be added by Composer into include_paths.php like:
vendor/composer/include_paths.php: $vendorDir . '/pear/net_url2',
which failed to do so. To generate autoload files again, run this command:
composer dump-autoload -o
and check whether the autoload files under vendor/composer has been generated as expected.
To test that out, I've run this PHP command and it worked:
php -r 'require_once "vendor/autoload.php"; require_once "vendor/pear/http_request2/HTTP/Request2.php";'
Note: To see the failing scenario, remove include of autoload.php.
For a Symfony based console application, I need to read the it's version number from it's composer file (not branch alias), programmatically.
Manually, I can use the composer show -s to get the root package information, but there does not seem to be any command to to get the clean version of my package.
The purpose is to automatically display the installed package version, when running the application, without having to deal with *.txt files or other file-based ways that contain a semantic version number.
Sadly I am not familiar with composer's architecture, so I have no idea what components I can use to achieve this.
Any ideas or perhaps already made packages that solves is mostly welcome.
I know its kinda late reply but you can read the info from a JSON file which is written by composer.
the file is located at vendor/composer/installed.json.
Read the JSON, parse it, and get the info you want.
This package does that some what.
Install Composer in your project
composer require composer/composer --dev
example.php
<?php
// Include Composer Autoload
require __DIR__ . '/vendor/autoload.php';
use Composer\Factory;
use Composer\IO\NullIO;
$composer = Factory::create(new NullIo(), './composer.json', false);
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
foreach ($localRepo->getPackages() as $package) {
echo $package->getName() . PHP_EOL;
echo $package->getVersion() . PHP_EOL;
echo $package->getType() . PHP_EOL;
// ...
}
I have started a composer project and have included phpspec-st,
when I run the command:
/var/www/yii-video-site/vendor$ bin/phpspec desc videosite/test
I get the message:
Specification for videosite\test created in /var/www/yii-video-site/vendor/spec/videosite/testSpec.php.
But when I run phpspec,
it says test
test
10 ! it is initializable
class test does not exist.
videosite/test
10 ! it is initializable
class videosite\test does not exist.
Do you want me to create `test` for you?
Why isnt it seeing the classes that are already created?
You probably need to set-up your PSR-0/PSR-4 autoloading in your composer.json file. For example, if you had your namespaced classes in a "src" directory: something like src/Videosite/Test.php then you'd set the following for the autoloading in your composer.json:
"autoload": {
"psr-0": { "": "src/" }
}
Also, you are running phpspec from within the vendor/bin, so it may not know where the root of your project is. If you set your bin directory in composer.json, you can run phpspec from the bin directory in the root of your project, instead of from inside vendor/bin:
"config": {
"bin-dir": "bin"
}
I came across the same problem today. I tried to run composer dumpautoload on my terminal and it did solve the problem.
I have some config files of US state counties, for example:
config/
state/
alabama/
counties.php
alaska/
counties.php
...
And on my development localhost server, I call them with:
Config::get('state/alabama/counties');
and it works, it loads an array of counties which I display somewhere.
But when I deploy this app on the Heroku, they won't show up.
I was thinking that it maybe has a problem with treating the config/state/subfolder as an environment config?
I do have a config/staging subfolder, in which I have new DB config stuff, and it works with no problem,
but on the Heroku app, the states just won't show up.
Have you added this directory to your autoload mapping in composer.json and then run composer dump-autoload? Without this, Laravel doesn't know to load your new files in to consideration.
Composer is a CLI-run file that exists in the Root of each laravel installation. composer.json is the config file for Composer - it uses this to manage your dependencies.
There's a section in composer.json called "autoload." These are the files that will automatically be loaded each time the app boots. Mine looks like this:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/core"
]
For each folder that didn't exist before and that I wanted Laravel to understand, I added an entry here. Then, I ran composer dump-autoload and Laravel "understood" where the files I wanted to use were.
Each time you add a file, class, repository - anything that you want Laravel to automatically use, you'll have to run composer dump-autoload.
P.S: If composer dump-autoload doesn't work, try composer.phar dump-autoload.