I'm pretty new to PHP and Symfony and I just don't seem to use the Filesystem Component right.
I've followed the offical documentation, found under:
https://symfony.com/doc/current/components/using_components.html
and tried to install it, but I just dont get where I'm supposed to write the code to.
The docs say:
Once Composer has downloaded the component(s), all you need to do is include the vendor/autoload.php file that was generated by Composer. This file takes care of autoloading all of the libraries so that you can use them immediately:
// File example: src/script.php
// update this to the path to the "vendor/"
// directory, relative to this file
require_once __DIR__.'/../vendor/autoload.php';
use Symfony\Component\Finder\Finder;
$finder = new Finder();
$finder->in('../data/');
// ...
but where do I have to change this line?
in the vendor/autoload.php? Appreciate any help :)
If you are using Symfony framework, you don't need to install this component. It's altready included in symfony/symfony and is already registered.
You can simply use it like:
use Symfony\Component\Finder\Finder;
$finder = new Finder();
See this doc
Related
I have to load a Google plugin into the Cakephp 3.9 Application and need to be used inside the controller.
Google plugin places inside the Vendor folder
vendor/Google
Anyone can help for below points
How to load Plugin
How to import into the controller
I have used below link for reference:
https://api.cakephp.org/3.9/class-Cake.Core.Plugin.html
I use Google_Client in CakePHP - you shouldn't have to do anything special to use it. If it's installed via composer it's already in Composer's autoloader, you can call it directly.
Ex. In composer.json after running ./composer.phar require google/apiclient:"^2.7" My require section lists the Google API:
"require": {
"google/apiclient": "^2.7",
Make sure you run ./composer.phar install if it wasn't already installed durring require.
Then in to use the library, I just call it directly, prefixed with \ since it's not namespaced:
public function index()
{
$client = new \Google_Client();
If you're curious how this works under the hood - Composer will generate all the information it needs to load classes durring require or install and sticks these in several files back in vendor/composer, such as autoload_namespaces.php, where it should automatically have added Google_ to the list there, ex:
<?php
// autoload_namespaces.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
// Lots of class prefixes, but eventually:
'Google_' => array($vendorDir . '/google/apiclient/src'),
Classes that are namespaced to industry standards like PSR-4 (like all modern PHP libs probably should be!) are probably in autoloader_psr4.php - and so on. It registers it's own autoloader in ClassLoader.php, and sticks a reference to this in vendor/autoload.php - which Cake calls essentially on near line 1 of
webroot/index.php:
require dirname(__DIR__) . '/vendor/autoload.php';
So in short - you don't need to worry about autoloading again so long as you're working through Composer.
Also - if you're able to use an IDE which helps with autocompletion of class namespaces, like PHPStorm, that might make things easier.
For libraries that specify autoload information, Composer generates a vendor/autoload.php file. You can simply include this file and start using the classes that those libraries provide without any extra work:
require __DIR__ . '/vendor/autoload.php';
For more references : https://getcomposer.org/doc/01-basic-usage.md
I was wondering, I am currently trying to change my programming style to work with composer and its package system (my god why didn't I use it sooner?) but I was wondering I am trying to work following the PSR-4 standard.
And got the following php file
<?php
require_once(__DIR__ . '/vendor/autoload.php');
$class = new vendorname\packagename\classname;
$example = new vendorname\packagename\subpackage\classname2;
Is that good practice to use with composer and the PSR-4 standard?
Where the the classes are existing in:
- /vendor
-- /vendorname
--- /packagename
--- /src
---- classname.php
---- /subpackage
----- classname2.php
I am currently thinking it is, but I just want to make sure that I am using it correctly according to the PSR-4 standard :-).
Typically that is the way to go, but some packages use different namespaces (mainly packages that need to have legacy support, for as far as I have encountered). Therefore after you composer require the package and it's installed, you should check the files for the namespaces that are used. But yes, you are right, because the way you say it is how it's typically done.
Also usually the package's readme/website has some examples on how to construct their objects.
Example: The Monolog logger package has a file /vendor/monolog/monolog/src/Monolog/Logger.php that is in the Monolog namespace, not in the Monolog\Monolog\Src\Monolog namespace. Just be sure to check it, but most of the times examples on the package maintainer/owner's website will tell you how to use the package. In this example the readme on Github tells you how the package is used.
Most of packages include readme referring it's namespace. you can access classes using that namespace. if you can't found you can check from 'your_project_root/vendor/vendor_name/package_name/composer.json'.
"autoload": {
"psr-4": {"Monolog\\": "src/Monolog"}
},
For this example 'Monolog' is the namespace and this is the best way to follow psr standards.
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
// add records to the log
$log->warning('Foo');
$log->error('Bar');
You can see all this standards in https://www.php-fig.org/psr/
Additionally you can check how this packages loaded in 'autoload_psr4.php' located in
'your_project_root/vendor/composer/autoload_psr4.php'
when you run composer require, composer update or composer dump-autoload command. this file will updated.
I'm trying to find the base directory of my application from within a composer package. Is there an composer API or proper way to accomplish this.
To clarify, if my package install looks like this and I've got files here (using psr-4):
/home/project/vendor/Acme/my-package/src/
how can I find /home/project dynamically?
Updated Info:
I'm trying to load a .env file from the root which contains an API URL endpoint via Dotenv package from within the package.
This should do:
<?php
$root = null;
// Set the current directory.
// Make sure you set this up so
// that you get out of your own root.
// Assuming this php file is at the root
// of this composer package, this should suffice.
$directory = dirname(__FILE__);
// Go up until you find a composer.json file
// which should exist in the ancestors
// because its a composer package.
do {
$directory = dirname($directory);
$composer = $directory . '/composer.json';
if(file_exists($composer)) $root = $directory;
} while(is_null($root) && $directory != '/');
// We either are at the root or we got lost.
// i.e. a composer.json was nowhere to be found.
if(!is_null($root))
{
// Yay! we are at the root.
// and $root contains the path.
// Do whatever you seem fit!
bootstrapOrSomething();
}
else
{
// Oh no! Can we default to something?
// Or just bail out?
throw new Exception('Oops, did you require this package via composer?');
}
#sven There may be situations where this strategy might help. Like a general console app (phar) for any project and to avoid global installation but still load a bootsrap file. Composer allows bin files to be installed at the root https://getcomposer.org/doc/articles/vendor-binaries.md, but allowing users to place the phar file wherever they see fit is a plus.
One could argue about inversion of control, but imo, simplicity should come into play sometimes.
Ah.. I think I've figured it out..
Since I used include_once './vendor/autoload.php'; in my index.php I can just use getcwd() from the package
Based in input from #Sven best and cleanest solution was to collect input on class initialization and leave configuration out of the package.
Try saboohy/basepath package. Gives directory of the project.
I currently use the F3 autoloader to load F3 from /lib/f3 and my app code from /app
My config for AUTOLOAD is AUTOLOAD="lib/f3/;app/;
So now I can do things like
$user = New \Models\User;
echo \Template::instance()->render('layout.html');
I want to also autoload other libraries but I seem to be having trouble. When I add them to /lib I also change the autoload: AUTOLOAD="lib/f3/;app/;lib/;
For example, lets try this class:
https://github.com/tpyo/amazon-s3-php-class
I put S3.php in /lib I also put it in /lib/S3
...Still I cant do things like
$s3 = new \S3(....);
$s3 = new S3(....);
$s3 = new \S3\S3(....);
Nothing works without require_once 'lib/S3/S3.php';
I have the same problem with Swiftmailer, MPDF and anything else I try.
What am I missing here? How can I easily install Composer compatible libraries which should autoload?
This worked for me when it comes to Composer: in your F3's index.php require composer autoloader:
require_once 'PATH_TO_YOUR/vendor/autoload.php';
And it will load all your Composer files. Simple.
F3 framework creators build their own autoloader but it doesn't stop you from loading Composers' (see this thread on F3's GitHub)
I am trying to use this composer package with a new project I am working on https://packagist.org/packages/activecollab/activecollab-sdk. However when i try and create a new class I keep getting the following errors.
Fatal error: Class 'ActiveCollab\Client' not found
The file that is throwing this error looks like this.
require "vendor/autoload.php";
new ActiveCollab\Client;
Which is just being used to test if the files are being loaded in properly. The composer.json of the file which I am trying to use looks like such. And I have a feeling the problem is in this file but I can't figure out what.
stuff...
"autoload": {
"psr-0": {
"ActiveCollab\\": "ActiveCollab"
}
}
...stuff
Also looking at the autload_namespaces.php file it is being generated as such.
<?php
// autoload_namespaces.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'ActiveCollab' => array($vendorDir . '/activecollab/activecollab-sdk/ActiveCollab'),
);
I have used psr-0 in some composer packages of my own and everything looks to be right except maybe the camel case in the namespace but i don't see this as being disallowed in the php proposal for psr-0.
Thanks for any help this has been driving me crazy.
The thing is: You cannot simply add a composer.json file with a random autoloading configuration and hope that it works - it actually has to match the naming scheme you are using. That is what this project got wrong, and nobody tested it. Which probably means nobody uses this library, and you can expect no support from the creators due to lack of interest.
But let's see how they react on my pull request to get things back to working again.
The composer config looks fine: Is it just the case that you omitted the leading \ from your class name?
new \ActiveCollab\Client;
You'll need that if your code is inside another namespace, as it will load it relative to the current namespace.
EDIT: I've just checked out that library, and even with the above fix, the autoloader wasn't quite working. The autoloader may also be broken due to the composer.json file for the library specifying a PSR0 autoloader, but using ".class.php" extensions (not PSR0 compatible). An autoload.php file is included with the library, so if you just require that file, you should be able to use the classes:
require 'vendor/activecollab/activecollab-sdk/ActiveCollab/autoload.php';
After doing this, I was able to use the class.