I'm using PhpStorm and Deployer so I included deployer.phar in PHP Include paths to have auto-completion in deploy.php file. After including the whole deployer.phar PhpStorm complains about duplicate class definition - one coming from my app vendor directory, and second from deployer.phar vendor directory.
Is it somehow possible to configure PhpStorm Include paths so only some parts of PHAR file (ex. only the src directory) are included? This doesn't work:
/path/to/deployer.phar/src
nor this:
phar:///path/to/deployer.phar/src
I want to avoid installing deployer/deployer as composer dev package.
EDIT
It seems that even adding single PHAR file in Include paths is kind of a hack.
It's not possible currently. As a workaround you can unpack deployer.phar somewhere and add extracted deployer.phar/src to Include paths. Not convenient, but would work.
Related
I just inherited a composer project in a very bad shape. They sent me a zip file with the vendor directory in it and I suspect that the previous developer has edited files directly inside vendor.
Is there a way to "validate" the vendor folder to ensure that the files inside are unmodified?
Change the name of the old vendor to something else.
Execute composer install again.
Run diff to compare both directories.
E.g. for a sample project where I intentionally modified a single file inside vendor.
$ mv vendor vendor_old
$ composer install
### install output...
$ diff -rq vendor vendor_old
Files vendor/autoload.php and vendor_old/autoload.php differ
Files vendor/composer/autoload_files.php and vendor_old/composer/autoload_files.php differ
Files vendor/composer/autoload_real.php and vendor_old/composer/autoload_real.php differ
Files vendor/composer/autoload_static.php and vendor_old/composer/autoload_static.php differ
Files vendor/symfony/console/Terminal.php and vendor_old/symfony/console/Terminal.php differ
You can mostly ignore the changes to the autoload* files, but with this listing you can concentrate in those other files that report differences (and run a more exhaustive diff from them).
In the example, only vendor/symfony/console/Terminal.php was actually modified.
Copy the project into some other folder, and delete the vendor directory. Run composer install and compare two vendor files.
The easiest way to do this is by using composer status command.
The prerequisite is that package is installed from source (as described on the official Composer site):
If you often need to modify the code of your dependencies and they are installed from source, the status command allows you to check if you have local changes in any of them.
I want to use aws-sdk for php client in a custom module of drupal. I need to include vendor/autoload.php in module. But when I include it, it gives me error. I have tried to include many ways but did not get success. I added it as:
require __DIR__.'/vendor/autoload.php'; at the top of the file of .module file. Then the website gets crashed. Please could you tell how I should use require __DIR__.'/vendor/autoload.php';
I'm not sure about how drupal handles autoloading of external php modules. But with the experience of working with frameworks like laravel, cakephp and with composer, I'm sure that the target file which is index.php which routes to a number of different controllers in root directory already includes vendor/autoload.php. If it does not include, add the require statement which points to autoload.php relative to index.php or absolute path. Then using namespaces in php, you can use external php modules which are then autoloaded.
require __DIR__.'/vendor/autoload.php'; // Incase vendor directory is in same level as index.php file
require dirname(__DIR__).'/vendor/autoload.php'; // Incase vendor directory is in parent level as index.php file
It's hard to know without the actual error message. If you're getting a white screen you need to enable display of full errors (admin/config/development/logging) so you can see what's actually going on and if the classes you're relying on aren't being included in the first place, or there's some sort of conflict (remember also to clear the cache after changing anything significant).
Here's how I've gone about adding 3rd party packages in custom D7 modules:
generate a composer.json file that installs it in vendor/
require vendor/autoload.php from [modulename].module
In detail:
change to module directory
run composer init
follow prompts (it'll ask "Would you like to define your dependencies interactively" - choose yes then you can search by name)
use drupal-module for type
you can use "proprietary" for license if you don't want anyone else to use your code, this the composer.json validate cleanly (composer validate)
When finished you should have a vendor directory that includes an autoload.php file and /composer directory. "Require" this from your .module file, e.g.:
require 'vendor/autoload.php';
drush cc all
You should now be able to use your code.
Note there's a Drupal module called xautoload - (in my opinion) overkill for this.
I had wondered if a simple files[] = line for the autoload.php in [modulename].info would work - it doesn't, regardless of order.
I need to dump my autoloader every time I add a new class. I am using psr-4. I don't really know why I need to do so. In psr-4 it should automatically load the classes. Where am I going wrong?
Here's my composer.json file
{"autoload": {"psr-4": {"MyDomain\\": "app"}}}
Here's my directory structure:
Here's the code for one of my classes:
<?php
namespace MyDomain\Model;
class Employee {
}
?>
PSR-4 (and also PSR-0) requires that the class ClassName is stored in a file named ClassName.php. The names are case sensitive and they must match exactly.
The file names in your project are lowercase, the class names are mixed case. The default disk formats on Windows and macOS are case-insensitive on search. This means when a program searches for Employee.php and the file employee.php exists in the directory, the search succeeds and the OS returns the existing file even if the case of its name is not the same as the case of the required file. On Linux-based OSes, the default disk format is case sensitive and a program that searches for Employee.php cannot find employee.php.
Your composer.json file declares the app/ directory as the root directory of the MyDomain namespace that follows the PSR-4 standard. This is enough for the autoloader to find the file app/Models/Employee.php when it needs to load the class MyDomain\Models\Employee.
Because you run it on Ubuntu (which is a Linux-based OS), PHP cannot load the Employee.php file (because it doesn't exist) and the OS doesn't provide it the file employee.php instead.
It seems that you generate the autoloader using composer update -o or composer dump-autoload -o. The -o (short of --classmap-authoritative) tells Composer to scan the directories declared in composer.json (app/) in your case and create a classmap that contains all the classes it can find. A classmap is a list that maps the classnames (with the namespace) to filenames (with directories). This way, the autoloader knows exactly where to find each class and the loading goes faster.
The above two paragraphs explain why you need to regenerate the autoloader after you add a new class.
The correct way to do the job is to follow the PSR-4 requirements. To be more specific, each namespace under MyDomain must be stored in a subdirectory of app/ that has the same name, including the case. Each class must be stored in the correct subdirectory, in a file that has the same name as the class (including the case) and the termination .php (lowercase). For example, the class MyDomain\Models\Employee must stay in the file app/Models/Employee.php.
After you fix the file names you can run composer dump-autoload and forget about it. As long as the class and file names follow PSR-4 the autoloader will find them without regenerating it again.
On the production server you can run composer dump-autoload -o to improve its speed a little. Just don't forget to run it again after each deploy (or, even better, include the command in the deployment script).
I have a local project with loaded with Composer libs. I uploaded this project to my FTP and received errors, connected with not found classes from some libs.
Can I simply copy vendor/ folder to FTP or I missed something?
Error received:
Fatal error: Class 'AAA\Core\Tools' not found in /home/aaa/public_html/api.php on line 11
api.php:
<?php
use AAA\Core\Tools;
require_once("./vendor/autoload.php");
require_once("./api/" . Tools::getFieldValue('controller') . ".php");
All works fine on localhost!
Linux has a case sensitive file system. That means that files Alex.txt and alex.txt are the same thing in Windows, but not in Linux. Actually on Linux both can happily live in the same directory:
$ tree .
.
├── alex.txt
└── Alex.txt
0 directories, 2 files
Taking this into consideration, I would try to double check that the paths you are using in your namespace are actually identical to what is found at the file system level. (i.e: AAA directory with only uppercase letters ; Core directory capitalized and Tools.php file capitalized)
If you want to keep your existing file system layout, you can use PSR-4 to explicitly tell Composer how to map the namespace to the file system:
Change autoload section from your composer.json:
{
"autoload": {
"psr-4": {"AAA\\DB\\": "db/"}
}
}
where db/ is the actual path from the file system
Update the autoloader:
$ composer dump-autoload
This will take care of directory names, but doesn't apply for files. Meaning that any file inside db/ must be named exactly as used in namespace (for a usage as use AAA\DB\DBCore the file must be db/DBCore.php).
If your file is named dbcore.php and you want to reference it in your namespace as DBCore, you can use classmap feature from Composer:
"autoload": {
"classmap": [
"db/dbcore.php"
]
}
dbcore.php:
<?php
namespace AAA\DB;
class DBCore
{
}
And you can use it as usual:
<?php
require_once("./vendor/autoload.php");
$dbCore = new \AAA\DB\DBCore();
Firstly I would check the autoloader files composer has generated to make sure the paths are valid on your linux server.
Another simple but common issue is that on windows the folder and file names are not case sensitive however they are on Linux. Double check that the folders and files have the correct case as if not it won't find them to auto load.
Rather than trying to upload via FTP which I think is going to be tricky if not impossible to get right, I would suggest you explore getting composer working on your hosting environment.
Composer is entirely PHP based, so should run anywhere that PHP is running.
If you don't have command line access, you can use something like PHPShell which gives you a PHP based command line on which you can then run Composer.
See this other SO answer to get some tips on how to use PHPShell.
Another option is to build a little PHP wrapper that you actually run by visiting it in your browser, in the classic PHP way. See this other SO answer for some tips on how to do that.
Bottom line, you should really look at getting Composer running on your server rather than trying to bodge it another way.
Once you have done your composer process on the server, you must remove the PHPShell or composer wrapper you created so that you don't leave any security holes.
Did you tell the composer where your Class 'AAA\Core\Tools' is?
You can even add your own code to the autoloader by adding an autoload field > to composer.json.
{
"autoload": {
"psr-4": {"Acme\\": "src/"}
}
}
Composer is not meant to be used that way (i.e. you shouldn't be manually transferring vendor directories from one environment to another).
As you add dependencies to your project, the composer.json file will contain those dependencies. When you run composer install or update on your localhost, it "locks" the current version of those dependencies for your project and stores them in the composer.lock file. You should be transferring the composer.json and composer.lock files from your development environment to your production environment and then running composer install on your production environment as part of your deployment process. When you run composer install on your production environment, Composer will look at your composer.lock file and install the specified versions of the dependencies in the vendor directory of the production environment.
You may want to review the composer documentation regarding basic usage (https://getcomposer.org/doc/01-basic-usage.md) and command line options (https://getcomposer.org/doc/03-cli.md) for more details.
What is xamppfiles/lib/php for?
And I see that path is in PHP's include_path but it's not set in php.ini so I guess XAMPP includes it internally.
What do those php files do and why are they included by default?
I just installed an application that does include('config.php'); trying to reference a file from the same directory it's in, but ends up including xamppfiles/lib/php/config.php instead and has a name clash with class Config.
How can I avoid including XAMPP's php files or otherwise avoid this problem?
You can remove the "Config" pear package that comes with XAMPP. This package ships the "Config.php" file that uses the same name that your application.
sudo xamppfiles/bin/pear uninstall Config