I got no clue why AWeberAPI is not found. Any help is appreciated.
php code:
require('vendor/autoload.php');
new PHPExcel;
new AWeberAPI;
composer.json:
{
"require": {
"aweber/aweber": "^1.1",
"phpoffice/phpexcel": "^1.8"
}
}
The problem
The module doesn't appear to be properly configured for use/autoloading with composer. They may have just added the composer configuration to allow you to easily install it, but not to use it within the composer autoloader.
The generic convention for it is that AWeberAPI should match the package's PSR-4 autoloader format, which says "look in aweber_api", then it will look for a class named AWeberAPI.php. You can test this behaviour is correct by adding this file:
<?php
// File: vendor/aweber/aweber/aweber_api/AWeberAPI.php
class AWeberAPI {
public function __construct() {
die('yeah, it works now...');
}
}
Then try your script again, the class will exist now.
What can I do?
Well - you could submit a pull request to their repository to fix it, but it looks like it would involve renaming the classes and filenames which would be a breaking change so I probably wouldn't bother.
You can get it to work by requiring the actual source of the API library instead of the composer autoloader in this case:
require_once 'vendor/aweber/aweber/aweber_api/aweber_api.php';
Related
I have a project, and I need some packages, so I reorganized the project to use PSR-4.
Here's my composer.json:
{
"name": "me/production",
"type": "project",
"authors": [
{
"name": "Me",
"email": "me#me.com"
}
],
"config": {
"platform": {
"php": "5.6.1"
}
},
"autoload": {
"psr-4": {
"API\\": "api/"
}
},
"require": {
"nesbot/carbon": "^2.25"
},
}
it doesn't work in my scripts. But, here's the real kicker: I do require_once __DIR__ . '/vendor/autoload.php'; in my php console, and it doesn't work either. I have triple and quadruple checked the path, the autoload is there.
What do I mean by "doesn't work"? the autoload requires successfully. It allows me to use libraries. BUT actual instantiations result in a
Class not found error.
Not only for my classes in the API namespace, which are namespaced in the top of the file and are exactly in the folder they're suppose to be, but I also CANNOT instantiate Carbon. I can use Carbon\Carbon but any attempt to instantiate will fail.
Interestingly, instantiation of \Carbon\Carbon directly does not fail.
What's going on? This is weird.
Thank you in advance.
EDIT: I tried redumping the autoloader, I also tried removing the vendor folder and reinstalling. All to no avail.
EDIT: May be worth mentioning I downgraded carbon to ^1.21 because carbon 2 doesnt support php 5.6. But it still doesn't work.
EDIT: It happens with my API namespace as well, here's an example using my implementation of the Instagram API:
use \API\Insta;
php > var_dump(new Insta);
PHP Fatal error: Class 'Insta' not found in php shell code on line 1
php > var_dump(new \API\Insta);
object(API\Insta)#3 (1) {
["ig_token"]=>
string(51) "A_VALID_TOKEN"
}
php >
EDIT: The problem solved itself, it has now mutated into one I care very little about: I can use everything but not in the php console. I am not sure what fixed it.
As you found out, nesbot/carbon, version 2.25 requires at least PHP v7.1.8.
Just having a use statement doesn't check anything, instead it creates a local alias that can be used. If you try to use something that does not exist, only then would it fail.
Please clarify that you have the following directory structure:
./composer.json
./composer.lock
./Api/Insta.php
and in the file Api/Insta.php:
namespace API; // this is your top namespace name
use Carbon/Carbon; // etc
class Insta { ... }
Having the namespace different to the directory name can lead to confusion.
There will also be the index.php/front-controller that pulls in the vendor/autoload.php file and presumably runs the framework.
I am working on a new tokenizer class for PHP_CodeSniffer. This also requires making a new Standard since the valid tokenizers are specified within each standard.
My new classes are using the same namespaces as the “sibling” classes from the original codebase.
If I use composer to install my project, and run phpcs, the auto loader seems to pick up my new classes just fine. PHP_CodeSniffer will load my tokenizer by calling:
$className = ‘PHP_CodeSniffer\\Tokenizers\\’ . $type;
$class = new $className(<stuff>);
Similarly, my custom standard has a use statement for a class in the original codebase. When running phpcs, no error are thrown.
When I try to run a test file through phpcs in a unit test, I get an error that my custom sniff file is unable to find the class in the use statement. My guess is this is auto-loading related. The bootstrap.php file for phpunit requires __DIR__ . ‘/../vendor/autoload.php’.My project composer.json has:
“autoload”: {
“psr-4”: { “PHP_CodeSniffer\\”: “src\” }
},
“autoload-dev”: {
“psr-4”: { “PHP_CodeSniffer\\Tests\\”: “tests\” }
}
Is there an issue with using the same namespace as the original code? With registering the same namespace to a different location in composer? Why does it work in runtime but not in testing?
It turns out PHPUnit has its own custom bootloader. When I added a require_once() for that in my PHPUnit bootloader, it loaded successfully. Thanks to a user on the PHP subreddit.
I have been beating my head for a couple hours trying to figure out why the autoload is not working for "Authentication\auth()". The "dBase\db()" class is loading just fine, but i'm getting:
Error: Class 'Authentication\auth' not found in
/var/htdocs/dev/test.php on line 8
when calling test.php.
Root composer.json -
"require": {
"geeshoe/dbClass": "dev-develop",
"geeshoe/authClass": "dev-master"
},
"autoload": {
"psr-4": {
"dBase\\": "vendor/geeshoe/dbclass/",
"Authentication\\": "vendor/geeshoe/authClass/"
}
}
authClass.php header -
<?php
namespace Authentication;
use dBase\db;
class auth extends db
{
test.php -
if (file_exists("vendor/autoload.php")) {
require "vendor/autoload.php";
} else {
echo "Dam.. Something went wrong!";
}
$test = new \dBase\db();
$var = new \Authentication\auth();
If someone could point out the obvious to me, that would be great. On a side note, autoload is not specified in the authClass->composer.json file for testing purposes.
The problem here is that in fact you don't use PSR-4. In PSR-4 class name should match file name. For db class its fine because db class is located in db.php file, but auth class is located in authClass.php file and that's the problem. You should update file name to auth.php
You might need to run:
composer dump-autoload
Also keep in mind in real packages, one vendor package has one namespace, so you don't create multiple namespaces for single package but only single
I want to include class Proxy from
./proxy/Proxy.php in ./index.php
require_once 'proxy/Proxy.php';
$proxy = new Proxy();
But next I want to use namespaces so I made:
./proxy/Proxy.php
namespace proxy;
class Proxy
{
[...]
and
./index.php
$proxy = new \proxy\Proxy();
or
$proxy = new proxy\Proxy();
or
use proxy\Proxy;
$proxy = new Proxy();
and I always get:
Fatal error: Uncaught Error: Class 'proxy\Proxy' not found in /var/www/proxy/index.php
What is wrong?
Firstly, if you are going to use namepaces, make them PSR-4 autoloader compliant! Check this link:
http://www.php-fig.org/psr/psr-4/
In other words, I'm asking you to change your namespace to Proxy with a capital.
Secondly, to get autoloading working, you need to register an autoloader. You can do it yourself by checking this out http://php.net/manual/en/function.spl-autoload-register.php, or, the better way is to install Composer (https://getcomposer.org/).
Using Composer then, if you aren't currently using it, run composer init from your site root, which will generate a composer.json.
Inside the Json, add this entry:
"autoload": {
"psr-4": {
"Proxy": "src/"
},
},
That assumes all classes beginning with namespace Proxy go in the src directory.
Since you made changes to the autoloading config, run composer dumpautoload and it will generate fresh classmaps.
Finally, in your scripts, require_once 'vendor/autoload.php and you'll never need require a class again!
require_once 'vendor/autoload.php';
use Proxy\Proxy;
$proxy = new Proxy();
The convention is based on file path and name, so src/Proxy.php is namepace Proxy, class Proxy. src/Something/Else.php would be namespace Proxy\Something with class Else.
Have fun! :-D
Try the following inside your index.php:
include 'proxy/Proxy.php';
use proxy\Proxy;
$proxy = new Proxy();
This file with the class needs to be included in order to be accessible. Just calling its namespace isn't enough.
^^The comment from mega6382I should do the trick.
But I wanted to maybe help you any further in your development, I'd suggest you want to autoload the files when you need them? You can use PHP it's own autoloader for it: "spl_autoload_register!".
I'd also recommend you use some better namespaces, \proxy\Proxy makes no sense at all...
EDIT with important note: The package I want to include does not use composer autoload. I'd have to use their hacky one and I want to avoid that.
I know how composer mostly works and I have package that can be a dependency (that's important, I know how to make this work in one project, but that's not what I'm asking).
What I need?
Somebody requires my package
composer require tomas/my-package
It will install
It will autoload my package with PSR-4
It will autoload 3rd party package as well
I have already tried something like this:
"autoload": {
"psr-4": {
"MyPackage\\": "src",
"PHP_CodeSniffer\\": "../../squizlabs/php_codesniffer/src"
}
}
I've tried that in one of my dependencies and it doesn't work :(.
Also, I've already talked to the package author and he doesn't want to use composer autoloading. He prefers his own.
Thanks for any help!
None if these answer are related to problem I desribed, so I try to post best solution so far:
I got inspired in PHPStan, which has feture to autoload directories, that were missed in composer (practically same issue).
I've added RobotLoader:
composer require nette/robot-loader
Then create LegacyCompatibility class with static method:
use Nette\Loaders\RobotLoader;
// ...
public static function autoloadCodeSniffer(): void
{
$robotLoader = new RobotLoader;
$robotLoader->acceptFiles = '*.php';
$robotLoader->setTempDirectory(sys_get_temp_dir() . '/_robot_loader');
$robotLoader->addDirectory(getcwd() . '/vendor/squizlabs/php_codesniffer/src');
$robotLoader->register();
}
And I call it, when needed:
LegacyCompatibility::autoloadCodeSniffer()
Works like a charm. But still opened to better solutions +1 !
Github Permalink
You are doing one big NO-NO in your composer.json file: You are defining autoloading for code that is not in your package.
This will fail, as you found out already.
And I wonder why you are struggling with integrating the PHP Codesniffer, because that package has a working autoloading definition included. All you'd need to do is "require": { "squizlabs/php_codesniffer": "^3.0#RC" } (if you really need the latest 3.x release candidate, otherwise ^2.8.0 would be a better idea).
If you require PHP_Codesniffer instead of somehow referencing it in your autoloading, then Composer will do everything to integrate that package: download it, add it to the autoloader, and run it's code if necessary. And anyone depending on YOUR package will also get this dependency installed.
The only problem you state is that "it doesn't work", which is no sufficient description of a problem because you lack describing what you did in your code, and what error message you got. Also state what you expected to happen, and what happened instead (and how this deviated from your expectation if this isn't obvious).