How to use composer's autoload when I already use autoload? - php

I have a config.php file where I use autoload for all my personal classes
function __autoload($class_name) {
include __DIR__.'/classes/'.$class_name . '.php';
}
I need now to use a 3rd party class from composer which is located in
/vendor/guzzlehttp.
So my code is now:
require('Config.php'); // my config file: this is used in ALL site
require 'vendor/autoload.php'; // the copmoser
$client = new GuzzleHttp\Client([]); // call to the 3rd party class installed by composer
Which raises a 404 error : php searches GuzzleHttp in /classes
Uncaught Error: Class 'GuzzleHttp\Client' not found
I have no idea on how to solve that: I need to keep my own classes in /classes
I need to autoload them because all the website uses that.
So: how can I use classes installed by composer in my website?
My composer.json content is:
{
"require": {
"firebase/php-jwt": "^5.0"
}
}

Autoloaders can be stacked just fine, but you'll want a check in place to see if the file exists before trying to include it.
However, if you're using Composer already, just let Composer handle the autoloading.
Add a reference to your global namespace being loaded from the classes directory in your composer.json's autoload PSR-4 section:
"autoload": {
"psr-4": {
"": "classes"
}
},

__autoload() is deprecated and seems to be incompatible with current best practice, spl_autoload_register(), which is what Composer uses.
function myAutoload($class_name) {
include __DIR__.'/classes/'.$class_name . '.php';
}
spl_autoload_register('myAutoload');
But you should really look at moving your dependencies into that dependency manager that you already have, Composer.
For external libs that are already in Composer, like Guzzle: https://packagist.org/packages/guzzlehttp/guzzle
For internally-developed libs: https://getcomposer.org/doc/04-schema.md#autoload
Edit: on second look there's no reason #Devon's answer wouldn't work.

Related

PHP: Autoloading via PSR-4 is saying class not found

I am trying to use a class in my src folder, DependencyContainer, but it is saying class not found?
Index:
<?php
$dc = new \Mango\DependencyContainer();
File structure:
src/
DependencyContainer.php
index.php
composer.json
composer.json:
{
"name": "mqwerty/ioc-container",
"type": "library",
"require": {},
"autoload": {
"psr-4": {
"Mango\\": "src/"
}
}
}
DependencyContainer class:
<?php
declare(strict_types = 1);
namespace Mango;
class DependencyContainer
{
}
First you need to add the autoload file in your index like this
require __DIR__ . '/vendor/autoload.php';
And your index.php is going to sth like this
<?php
require __DIR__ . '/vendor/autoload.php';
$dc = new \Mango\DependencyContainer();
It will solve your problem
Autoloading doesn't just happen automagically; composer is set up to manage the creation and updating of your PSR autoloading based off the PSR settings of your composer.json.
Do a composer install in your CLI; that will generate the autoload files in the vendor folder based off of your composer.json and create a composer.lock file, even if you don't have any dependencies.
From there, you will need to bootstrap the autoload file before executing your code.
Hey this has already been solved many times but ill still explain just incase you didnt understand others questions.
So I had this problem once too and you can find it on my profile.
psr works based on your path. when you set your src path thats where it starts from,
for example, your layout is something like the following:
vendor
your-vendor-name
your-package
src
App.php
Class.php
composer.json
then your psr location should have this after the : "/src"
and before it should be something like the following:
"your-vendor-name\your-package\"
when using a class, make sure you composer class names start with an uppercase letter and the class inside matches the file name, make sure the class namespaces are something like this \your-vendor-name\your-package
and to use
$app = new \your-vendor-name\your-package\(then the class name you want to use, so lets say, Class.php, then you would put Class() here)
hopefully this should solve your problem

how to add a PHP library to TYPO3 extension without namespace?

I'm tyring to implement a custom TYPO3 extension to execute some php code. With my main class "hello world!" ist already working and i understand the use of namespaces.
But now I found a php Library that suits my needs. I pasted the lib folder in the "Classes" folder of my extension. But now I'm getting class not found errors because none of the lib classes have a namespace.
Unfortunately I couldn't find any tutorial/doc on how to add a library to a typo3 extension while dynamically adding a namespace to every class. I tried to override every class with a namespace but somehow this cant be the solution
here is a sample of my Main class that is working but as soon as I try to call "ServiceMailman" i get namespace error, well, because they have none
namespace Htwg\GiMailman;
require_once 'Service/ServiceMailman.php';
class GiMailman{
public function getMailinglists() {
$mm = new ServiceMailman('http://localhost', '', '');
}
}
I'm looking for a way to add a php library to the "Classes" folder without adding a namespace to every library class.
Update:
I installed the library on an externel path and added it to the composer.json in the classmap entry:
"autoload": {
"psr-4": {
"Htwg\\GiMailman\\": "Classes/"
},
"classmap": ["/opt/lampp/lib/php/Services"]
}
and it shows up in the autoload_classmap.php:
// autoload_classmap.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
...
'Services_Mailman' => $baseDir . '/../../../../lib/php/Services/Mailman.php',
'Services_Mailman_Exception' => $baseDir . '/../../../../lib/php/Services/Mailman/Exception.php',
);
But when i try to class the class in my Main php class it still can't be found:
namespace Htwg\GiMailman;
//require_once 'Services/Mailman.php';
class GiMailman{
public function getMailinglists() {
$mm = new \Service_Mailman('http://localhost:8001/3.1', '', 'password');
return "getMailinglists";
}
}
Any PHP classes that do not use namespaces are in the top level namespace. So you can use them like:
$mm = new \ServiceMailman('http://localhost', '', '');
You should not add external libraries to you Classes directory. Classes in this directory are autoloaded with the correct namespace for your extension (Vendor/ExtensionName). As external libraries have a different, or in your case no, namespace, this will cause problems. Usually we put external libraries in Resources/Private/Php/LibraryName. You will then need to require or include the library.
If you're using composer it is however better not to include external libraries inside your extension, but let composer worry about it if possible. That way you don't have to worry about autoloading (so you don't need to require or include any files manually) and any dependencies for the external library are also automatically resolved. Either require the library in your global composer.json or, if you install the extension that requires it through composer, add it to the composer.json of the extension.
If you're running composer there are two ways:
The library is available on https://packagist.org/ => Require it in your composer.json file
The library needs to be copied into e.g. Library/ServiceMailman/. After that you set it into your composer.json in the autoload section "classmap", if no namespaces exists for this library. More: https://getcomposer.org/doc/04-schema.md#classmap (If the library has namespaces, it should be in autoload section "psr-4")
If you're not running composer and want to include it in your TYPO3 extension easily, there is a good tutorial: https://insight.helhum.io/post/148112375750/how-to-use-php-libraries-in-legacy-extensions

Using Composer Packages with Slim PHP 2.0

I am trying to build a REST API using Slim PHP 2.0, Composer, and a couple third-party packages. I used Composer to install Slim by creating a composer.json file in the root of my application with the following:
{
"require": {
"slim/slim": "2.*"
}
}
After I ran composer install I have the following structure:
root/
vendor/
composer/
slim/
autoload.php
composer.json
composer.lock
index.php
I want to include the Valitron (https://packagist.org/packages/vlucas/valitron) library to do validation along with this Bcrypt (https://packagist.org/packages/openlss/func-bcrypt) library to hash passwords for users. So, I made the following additions to my composer.json file so the it looks like this:
{
"require": {
"slim/slim": "2.*",
"vlucas/valitron": "dev-master",
"openlss/func-bcrypt": "dev-master"
}
}
After I ran composer update I got the following directory structure.
root/
vendor/
composer/
openlss/
slim/
vlucas/
autoload.php
composer.json
composer.lock
index.php
From here, I am not sure how to set up the autoloading for my application. I sometimes see autoload classmap and other times see psr-0. On top of these third-party packages I am going to be creating my own models to use. One will be a base model that handles connecting to the database and then each table will have a model that I use to manipulate the said table with. So for interacting with the users table I will use my UserModel.php file below. My other question is how would I go about "using" the Valitron and BCrypt files within this one? Would I just do this:
<?php namespace Libraries;
use \Valitron;
use \BCrypt;
class UserModel extends BaseModel {
// I want to use the Valitron class here along with the crypt file
}
How would I go about setting up autoloader to accomplish this? Any help is greatly appreciated. I already dislike Composer a lot but since everyone is saying it's a must for PHP developers I am trying to force myself to learn it.
Composer provides an autoloader for third-party libraries specified in composer.json. See https://getcomposer.org/doc/01-basic-usage.md#autoloading. You can customise the autoloader for your needs, it supports both PSR-4 and classmap. See the autoload reference for more details.
I mean, it's pretty simple in reality. If you want these classes to be autoloaded, then require autoload.php
require 'vendor/autoload.php';
Or, in composer.json you can declare it.
{
"autoload": {
"psr-0": {"Libraries": "vendor/open-lss"}
}
}
Which will allow you to do:
namespace Libraries\func-bcrypt
class bCrypt_class{
}
which is what I believe you are attempting to achieve

ZF2: autoloading libraries without namespaces

Previously I have only been using third party libraries that use namespaces together with Zend Framework 2. Now I need to use a library that does not use namespaces, and I cannot seem to make it work. I installed it via Composer, and it is installed fine into the vendor directory. I am trying to use it as follows:
$obj = new \SEOstats();
The result is a fatal error indicating that the class could not be found. I have tried to manually configure the StandardAutoloader, but so far without any luck. I thought that the autoloading would be done for me automatically when installing through Composer, but I guess that is not the case without namespaces? I haven't seen any reference to the library in the autoload files that Composer generated. I guess I have to do it manually - but how?
Thanks in advance.
You can use the files and classmap keys.
As an example consider this composer.json:
{
"require": {
"vendor-example/non-psr0-libraries": "dev-master",
},
"autoload":{
"files": ["vendor/vendor-example/non-psr0-libraries/Library01.php"]
}
}
Using the files key you can then use
$lib = new \Library01();
Use the classmap key when you need to load multiple files containing classes. The composer.json would be:
{
"require": {
"vendor-example/non-psr0-libraries": "dev-master",
},
"autoload":{
"classmap": ["vendor/vendor-example/non-psr0-libraries/"]
}
}
Composer will scan for .php and .inc files inside the specified directory configuring the autoloader for each file/class.
For more info you can check http://getcomposer.org/doc/04-schema.md#files and http://getcomposer.org/doc/04-schema.md#classmap
If you are under a namespace while creating the object, you must use the "\" (root namespace), otherwise you will use the Library01 class under the current namespace (if you have one, if you don't have one you'll get an error).

add a library to silex

I know this question has already been asked, but it seems that autoloading process changed a little bit with composer.
I just want to add a class library to my silex project.
So I made this file:
vendor\lib\picture.php
<?php
namespace MyNamespace;
class Picture
{
function testage()
{
echo 'hihaaa ça marche'; exit;
}
}
in vendor/composer/autoload_namespaces.php, I added this line to the big array:
'MyNamespace' => $vendorDir . '/lib/',
And in the main file I added:
use MyNamespace\Picture as Picture;
and called it like that:
$app->register(new Picture());
which gives me this error:
Fatal error: Class 'MyNamespace\Picture' not found...
I just don't know how to add a class that I can use from any controller, easily, without command line (I don't use composer, I downloaded silex preconfigured), any idea?
If you're using composer you should not change the vendor directory. You should not add files into it, and you should not modify the composer-generated files.
I recommend you put those classes into the src directory. #gunnx shows how you can configure autoloading in composer.json, so that it gets re-generated every time you run composer install.
The file would be in src/MyNamespace/Picture.php. The autoload config in composer.json would be:
{
"autoload": {
"psr-0": { "MyNamespace": "src/" }
}
}
The actual solution is a combination of the two previous answers. But I think it's important to get the details right ;-).
Your Picture class should be in this file: vendor/lib/MyNamespace/Picture.php. Note the full namespace and the casing.
You can add your own code to the autoloader by adding the following to your composer.json
e.g.
{
"autoload": {
"psr-0": {"Acme": "src/"}
}

Categories