I'm working to create two symfony projects with one vendor directory
// I need to change this :
my-project1/
└─ vendor/
my-project2/
└─ vendor/
// To this :
vendor/
my-project1/
my-project2/
First of all, I would advise you not to do it (why do you want it anyway?), but answering the question: you have to set up vendor-dir in both projects to ../vendor.
Related
I am creating a PHP project and want to implement PSR-4 autoloading.
I don't know which files I need to create in the vendor directory to implement autoloading for class files.
If you are using composer, you do not create the autoloader but let composer do its job and create it for you.
The only thing you need to do is create the appropriate configuration on composer.json and execute composer dump-autoload.
E.g.:
{
"autoload": {
"psr-4": {"App\\": "src/"}
}
}
By doing the above, if you have a file structure like this
├── src/
│ ├── Controller/
│ ├── Model/
│ ├── View/
│ └── Kernel.php
├── public/
│ └── index.php
└── vendor/
After executing composer dump-autoload the autoloader will be generated on vendor/autoload.php.
All your classes should be nested inside the App namespace, and you should put only one class per file.
E.g.:
<?php /* src/Controller/Home.php */
namespace App\Controller;
class Home { /* implementation */ }
And you need only to include the autoloader in your entry-point script (e.g. index.php).
<?php
require '../vendor/autoload.php';
Which will allow you to simply load your classes directly from anywhere after this point, like this:
use App\Controller\Home;
$homeController = new Home();
This is explained at the docs, here.
I just installed composer to manage my project's dependencies.
But I end up with a problem: how to protect the files that composer created?
Shouldn't there be an .htaccess file at the root of vendor? (for my case at the root of the libsproduction folder)
Here is my composer.json file :
{
"config": {
"vendor-dir": "libsproduction/"
},
"require": {
"spipu/html2pdf": "^5.2",
"phpmailer/phpmailer": "^6.1",
"tinymce/tinymce": "^5.2",
}
}
Composer files (both the vendor directory and the composer.json and composer.lock files themselves) shouldn't be in a publicly accessible place.
But the way to do this is not to create an .htaccess or something similar under a webserver different from Apache. What you should do is serve a directory different than the one containing these directory and files. Nor changing the vendor name as you are doing.
The way this is generally done, by most (if not all) composer based frameworks, is to create a "public" or "web" directory which is the one you would configure your web server to actually serve, and put your application entry file(s) there.
E.g.
project-root-dir
├── public
│ └── index.php
├── vendor/
├── composer.json
├── composer.lock
The directory your web server should point to would be public in this scenario. So visiting users cannot directly see anything that's not within that directory.
To load composer's autoloader so that all packages classes are available, you simply do something like:
// public/index.php
require dirname( __DIR__ ) . '/vendor/autoload.php';
/* your application/script logic goes here /*
This way you can also put any other file that shouldn't be user accessible (configuration, logs, cache, etc) one level up from the publicly accessible directory, and you have work less to protect your sensitive files.
I'm developing a PHP component called php-app-config using composer.
This component, once required by another project, and installed using composer install, should look for config files inside the config folder of the root package, something like root_package/config/config.yml.
The ./config/config.yml should exists only in the root package and not inside the component imported by the "require:" in composer.json, as below:
▾ root-package/
▸ bin/
▸ build/
▾ config/
▸ locales/
config.yml
▸ src/
▸ tests/
▾ vendor/
▸ composer/
▸ phpdocumentor/
▸ phpspec/
▸ phpunit/
▾ robotdance/
▾ php-app-config/
▾ src/
Config.php -> how to get the root "config/config.yml" path from here?
▸ tests/
composer.json
composer.lock
phpunit.xml
README.md
The root package can be a web app or command line utility.
Is there any way to get the root package path using composer? If not, what is the better way?
Using ReflectionClass:
$reflection = new \ReflectionClass(\Composer\Autoload\ClassLoader::class);
$vendorDir = dirname(dirname($reflection->getFileName()));
You can use composer's very own \Composer\Factory::getComposerFile(); to get to the project root directory:
$projectRootPath = dirname(\Composer\Factory::getComposerFile());
And with your case, you can access your root-package/config/config.yml by:
$configYmlPath = $projectRootPath . '/config/config.yml'
Don't forget to add composer to your dependencies for the \Composer\Factory::class to be available:
$ composer require composer/composer
I would suggest "anchoring" your application (web or cli) by defining the root path as a constant.
When you have for instance a root-package/src/application.php file, it should know where it lives, something like define('APP_ROOT_FOLDER', dirname(__DIR__)); could help. Once the constant is declared, it's available for dependencies, too.
So, in /php-app-config/Config.php you would simply use the constant:
$config = APP_ROOT_FOLDER . '/config/config.yml';
(Or define a APP_CONFIG_ROOT_FOLDER constant which points directly to the config folder of the application.)
You could also try go some folder levels up from the dependency.
In php-app-config/Config.php you would use __DIR__, which is root-package/vendor/robotdance/php-app-config/src. Now, you would need to go 4 levels up to reach root-package/.
$config = __DIR__.'/../../../../config/config.yml';
This will not work out, when your application gets packaged as a PHAR.
Is there any way to get the root package path using Composer?
If you have the Composer object, you can get the path of the vendor directory from the Config object:
$vendorPath = $composer->getConfig()->get('vendor-dir');
then, go one folder up $config = dirname($vendorPath) . '/config/config.yml';
Using Laravel 5.x. or 5.1.x
What would be the basic recommended configuration for the .hgignore file?
Pulling from the .gitignore this is what I have:
syntax: glob
.env
.gitignore
.gitattributes
.idea
vendor/
node_modules/
Homestead.yaml
Homestead.json
Online I see for version 4 something about /bootstrap/compiled.php
Should I include /bootstrap/cache ?
I use negative lookahead to include the empty folder structure:
## Laravel specific
^\.env$
^vendor
## General
\.DS_Store$
[Tt]humbs\.db$
## Keep these folders, but ignore their content
^bootstrap/cache/(?!\.gitignore).+$
^storage/logs/(?!\.gitignore).+$
^storage/app/(?!\.gitignore).+$
^storage/framework/views/(?!\.gitignore).+$
^storage/framework/sessions/(?!\.gitignore).+$
^storage/framework/cache/(?!\.gitignore).+$
I'm beginning to study Composer and am developing a system where I separate the files core application files, as follows:
/root
|-- /src
|-- /App
|-- /DBConfig
|-- /Controller
|-- /Model
|-- /Core
|-- /Helper
|-- /Controller
|-- /Model
So, to set this setting in composer.json file and get access to all classes both /App much /Core would be this way?
"autoload" : {
"psr-X" : {
"App\\" : "/src",
"Core\\" : "/src"
}
}
Or is there a more correct way?
I have also read about PSR-0 vs PSR-4 and I am still somewhat in doubt which one to use. In my case what should I implement, PSR-0 or PSR-4?
You didn't need 2 entries just one for the main namespace so something like this for PSR-4:
"autoload" : {
"psr-4" : {
"MyApp\\" : "/src" }
}
As long as everything in src/ uses the same namespace that's all you'll need. Just let the autoloader do it's job.
As to which to use I'd go with PSR-4 because at some point it is expected that PSR-0 will be deprecated and as PSR-4 is made to be backwards compatible minus some warts for older legacy programs there isn't really a difference except of you start using some of it newer features