Autoloader from Composer clashing with other one - php

I am work on legacy app that includes dozens and dozens of different php scripts, all written before Composer was widespread in use.
I needed to use a package (for sending email) only available through Composer, so I created a composer directory and included it into one script like so:
include_once("/home/soccer/src/autoload.php"); // the old autoloader
require '/home/soccer/src/Mailgun/vendor/autoload.php';
use Mailgun\Mailgun;
Now the problem is that Composer's autoload (shown in line 2) works fine, and I can send mail, however now the important libraries from line 1 do not work:
PHP Fatal error: Class 'DB' not found in .....
There is a file at:
/home/soccer/src/DB.php
that is the most basic MySQL db loader imaginable. I tried adding a namespace to it with:
namespace Footyscores;
and then in the PHP script adding **Footyscores** to the function call, but no luck there, same error.
Here is the legacy autoloader:
include_once "/home/soccer/src/settings.php";
function __autoload($class)
{
global $srcDir;
$parts = explode('\\', $class);
$file = end($parts);
include_once $srcDir . $file . '.php';
}
How is I fix this? Thanks!

Related

Change namespace class autoload to manual require_once PHP

I want to use namespaces class to manual one without using autoload.php to be included. Because I don't want to use all function the class.
I am using this project https://github.com/codenix-sv/coingecko-api to get it's function in my php function.
In the example of using is like this
use Codenixsv\CoinGeckoApi\CoinGeckoClient;
$client = new CoinGeckoClient();
$data = $client->ping();
But I want to change it to require_once. So I put all src folder in my php folder and create this to call the function
require_once 'libs/Api/CoinGeckoClient.php';
$client = new Codenixsv\CoinGeckoApi\CoinGeckoClient;
$data = $client->simple();
First I got this error when trying to access the page.
Fatal error: Uncaught Error: Class 'GuzzleHttp\Client' not found in
C:\xampp\htdocs\te.st\libs\Api\CoinGeckoClient.php:35
Then I try to remove the line "use GuzzleHttp\Client" in CoinGeckoClient.php file.
And got with this error
Fatal error: Uncaught Error: Class 'Codenixsv\CoinGeckoApi\Client' not
found in C:\xampp\htdocs\te.st\libs\Api\CoinGeckoClient.php:35
Is there any way to just use the "simple" function of coingecko only in my php file.
https://github.com/codenix-sv/coingecko-api/blob/master/src/Api/Simple.php
Here is the way I fix this.
load in composer.json like
{
"require": {
"codenix-sv/coingecko-api": "^1.0",
"guzzlehttp/guzzle": "~6.0"
}
}
then do composer update in command window.
In my php file. make sure
use Codenixsv\CoinGeckoApi\CoinGeckoClient;
is placed in top of file. Then do the rest.
Thanks all
That package is prepared to works with composer.
Composer delivered autoloader, to make you work simplier.
If you remove use GuzzleHttp\Client line from CoinGeckoClient.php, there will be no way to send request to the server.
The best option is include composer autoload in your project file, it means you should:
Create composer.json file for you project
Add required library dependency using command: composer require guzzlehttp/guzzle
Add require library dependency using command: composer require codenix-sv/coingecko-api
Inside your project file add folowing line:
require_once(dirname(__FILE__) . '/vendor/autoload.php');
use Codenixsv\CoinGeckoApi\CoinGeckoClient;
$client = new CoinGeckoClient();
$data = $client->ping();
In other way, that will be necessarily to import all files manually. And of course, you haven't to forget about imports for Guzzle client.

Class Amp non found

I'm new on amphp and i'd like to try this very simple code first.
I downloaded amphp with composer for windows and save all folder created inside my project folder.
composer require amphp/http-client
Then my code is:
<?php
require __DIR__ . './autoload.php';
use Amp\Http\Client\HttpClientBuilder;
use Amp\Http\Client\HttpException;
use Amp\Http\Client\Request;
use Amp\Http\Client\Response;
use Amp\Loop;
$stringa = 'http://www.google.it/';
$request = new Request($stringa, "GET");
$location = $request->getHeader("Location");
var_dump($location);
But I get always 'Fatal error: Uncaught Error: Class 'Amp\Http\Client\Request' not found'
Any suggest?
I use wamp local server with php 7.0
Also ,after, I need to yield all the code...
Here are a few things that look for:
Did the autoload.php get included correctly?
I see there is an unnecessary . before /autoload.php.
Did you use the correct class name with the correct namespace?
Did you run composer require amphp/http-client so that the libraries will be installed?
Do the library's files exist inside the vendor/amphp/http-client directory?
If you're on Windows, use \ in the require statement.
Apart from these, I can't think of why the library won't load. I hope this helps.

Why Composer load ClassLoader in this way?

Open vendor/composer/autoload_real.php and look at this code:
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
When:
spl_autoload_register(array('ComposerAutoloaderInitf06647a07a90b762eb34553a7bce155e', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitf06647a07a90b762eb34553a7bce155e', 'loadClassLoader'));
Why Composer do this? And not this:
require_once __DIR__ . '/ClassLoader.php';
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
The reason is that multiple autoloaders might be present concurrently in one process if for example you run phpunit installed via composer, then your test bootstrap file will also include your project class loader, and so if we did a simple require it would redefine the ClassLoader class and do a fatal error. Using require_once would not work either since the ClassLoader.php file is present twice (one in PHPUnit, one in the project) with different paths. PHP would still include each of these once, leading in class redefinition.
This could be fixed with a simple if (!class_exists()) {} around the require, but unfortunately that kind of conditional class definition messes up APC on high traffic sites so we had to resort to this strange temporary autoloader hack to make it work everywhere.

Using Unirest php lib that has a namespace

I'm trying to use unirest, a new php lib for making rest calls.
I'd like to place it in a system-wide directory above my project. I then include it:
require_once ('../unirest-php-master/lib/Unirest/Unirest.php');
loads fine. Then I use it per the readme:
$response = Unirest::post(CSWA_URL ....
I get Fatal error: Class 'Unirest' not found in ...hello_world/sign_start.php on line 23
I then try to use the namespace (see the library's code. They use a Namespace Unirest statement before declaring the Unirest class.)
$response = Unirest\Unirest::post(CSWA_URL ....
I got further. Now: Fatal error: Class 'Unirest\HttpMethod' not found in ....unirest-php-master/lib/Unirest/Unirest.php on line 26 -- This is an error in the library code!
Q: Did I do something wrong? Did the authors of Unirest make a mistake? Do I have to place the library in ./lib? What's the best fix?
It looks like the Unirest code in Unirest.php relies on autoloading code from the two other files in the unirest lib directory (HttpMethod.php and HttpResponse.php).
The author suggests installing the package using composer, if you were to do that composer would add the Unirest namespace to the autoloader.php script it generates. From there you need to require the autoload.php file at the top of your script and it will handle loading classes that aren't defined.
Alternatively, if you don't want to use composer, I would just require the other two files in the unirest lib directory at the top of your script as well.

How do I load Zend Framework 2 database module only

Zend Framework 2 claims to have a "use-at-will" design that allows you to easily use any of its modules without committing to the full stack. I need a good database access layer, and from the docs and recommendations online I like the look of Zend\Db. I've placed the Zend/Db folder in my /lib directory, but I'm having trouble getting PHP to recognize the Zend\Db\Adapter\Adapter class. I keep getting a fatal error when I try to use it:
Fatal error: Class 'Zend\Db\Adapter\Adapter' not found in /home/username/public_html/test.php on line 6
I've tried setting ZF2_PATH in my .htaccess:
SetEnv ZF2_PATH /home/username/public_html/lib/Zend
I've tried setting the include path in my code:
set_include_path( $_SERVER['DOCUMENT_ROOT'] . '/lib' . PATH_SEPARATOR . get_include_path() );
I've tried explicitly loading and instantiating the Zend\Loader:
require_once 'lib/Zend/Loader/StandardAutoloader.php';
$zendLoader = new Zend\Loader\StandardAutoloader();
$zendLoader->register();
None of these have had any effect. I tried explicitly requiring Zend/Db/Adapter/Adapter.php, and that did fix the error I'm seeing, but then I just get the same error for one of its dependencies, so that's not a practical solution.
What am I doing wrong here? Is ZF2 just not really designed for this kind of modular usage, or am I missing something?
EDIT: I got this to work by writing my own autoload function:
function autoloader($class) {
$path = explode('\\', $class);
foreach ($path as $p) {
$cp .= DIRECTORY_SEPARATOR . $p;
}
include __DIR__ . '/lib/' . $cp . '.php';
}
spl_autoload_register(autoloader);
This sort of makes sense -- obviously if I'm using the db module without the rest of the framework, I can't expect the framework to do autoloading for me -- except I still don't understand why manually loading Zend\Loader didn't solve the problem. Isn't handling autoloading the point of Zend\Loader? Anyway, I have a workable solution for now, but if there's a better solution I'd love to hear it.
I strongly recommend you check out composer. It really simplifies managing dependencies between a ton of modern PHP libraries, as well as autoloading.
For instance, if you were starting you project, and you knew you wanted to pull in zend-db, you'd do something like this:
$ mkdir myproject
$ cd myproject
$ curl -s https://getcomposer.org/installer | php
$ ./composer.phar require zendframework/zend-db:2.1.1
That last line will cause composer to spring into action. It will create a directory called "vendor" where it keeps all the libraries it manages. It then will check out version 2.1.1 of zend-db in there, and set up an vendor/autoload.php which you'll require in your project.
Then you can test it out. Create myproject/index.php like so:
<?php
require_once "vendor/autoload.php";
$adapter = new Zend\Db\Adapter\Adapter(array(
'driver' => 'Pdo_Sqlite',
'database' => 'path/to/sqlite.db'
));
And it just works.
Later, if you decide you need Zend\Mail too, you just:
$ ./composer.phar require zendframework/zend-mail:2.1.1
and composer will install it, along with a couple of dependencies, and make sure it's available to the autoloader.
Composer is not ZF-specific, either. There's a whole ecosystem of code to explore. Packagist is a good place to start.

Categories