I am trying to use some zend framework components outside of zend framework but I am unable to do so.
Here is my composer file.
{
"require": {
"zendframework/zend-authentication": "^2.5.3"
},
"autoload": {
"psr-4": {
"Zend\\Authentication\\": ""
}
}
}
I was able to run composer update and install which has generated the autoload.php.
But when I try to use a the component I get "Fatal error: Class 'Zend\Authentication\Storage\Session' not found"
$session = new \Zend\Authentication\Storage\Session();
Is there anything obvious that I am missing from my setup?
I needed to require the autoloader
require __DIR__ . '/../vendor/autoload.php';
problem now solved
Related
I'm writing unit tests for my Shopware Plugin. I've setup the same PHPUnit environment as SwagPayPal.
What I did:
composer.json
[...]
"require": {
"ext-json": "*",
"php": ">= 8.0",
"goetas-webservices/xsd2php-runtime": "^0.2.16",
"enqueue/stomp": "^0.10.16",
"shopware/core": "6.4.12.0"
},
"autoload": {
"psr-4": {
"Namespace\\Plugin\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Namespace\\Plugin\\Test\\": "tests/"
}
},
[...]
phpunit.xml.dist bootstrap="tests/TestBootstrap.php"
TestBootstrap.php is a 1:1 copy of the same file from SwagPayPal
except ->addActivePlugins('SwagCmsExtensions') was removed. https://github.com/shopwareLabs/SwagPayPal/blob/10694e851a11ac60e98cdb2130e66724611ef9a6/tests/TestBootstrap.php
My tests were all working fine. I now added the following code in one test:
$customerRepository = $this->getContainer()->get('customer.repository');
$customerRepository->upsert([$customerData], Context::createDefaultContext());
After calling upsert it crashes with Compile Error: Cannot declare class Shopware\Core\Checkout\Promotion\Cart\PromotionProcessor, because the name is already in use
I can get it working when I run sudo rm -rf var/cache/test_* but only once. When running it a second time it crashes again.
It seems it loads Shopware from the vendor folder of the plugin and then also from the root folder. I don't get why it's working the first time, but not a second time.
Edit: I checked all my namespace declarations in the PHP test files and I'm pretty sure they're correct. So I think it's another cause I can't find.
This is caused by the classes being autoloaded multiple times. It's hard to say what causes this without knowing all the code involved. Rather than copying from an existing plugin I'd suggest you start from scratch and follow the documentation on how to setup a clean environment for your tests.
I just updated my tests/TestBootstrap.php to fix my problem.
I removed the ->setClassLoader(require dirname(__DIR__) . '/vendor/autoload.php') call, so it doesn't load the composer generated stuff anymore.
I added the following code so it adds the PSR-4 namespace prefixes for my plugin:
$pluginComposerDir = realpath(__DIR__ . '/..');
$pluginComposerJson = json_decode(file_get_contents($pluginComposerDir . '/composer.json'));
foreach (['autoload', 'autoload-dev'] as $loader) {
if (is_object($pluginComposerJson->$loader) && is_object($pluginComposerJson->$loader->{'psr-4'})) {
foreach ($pluginComposerJson->$loader->{'psr-4'} as $namespace => $path) {
$classLoader->addPsr4($namespace, $pluginComposerDir . '/' . $path);
}
}
}
So now I have best of both worlds:
My plugin only adds the autoload-dev namespace(s) for tests.
It doesn't load the composer dependecies of my plugin, so I get no collisions with the Shopware root or other dependencies
I need to install my plugin dependencies in the Shopware root and if I don't do it Shopware won't install my extension and warn me about the failed dependencies:
Failed Dependency: Required plugin/package "goetas-webservices/xsd2php-runtime ^0.2.16" is missing or not installed and activated
Failed Dependency: Required plugin/package "enqueue/stomp ^0.10.16" is missing or not installed and activated
Full tests/TestBootstrap.php:
<?php declare(strict_types=1);
// based on tests/TestBootstrap.php of SwagPayPal
/*
* (c) shopware AG <info#shopware.com>
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Shopware\Core\TestBootstrapper;
if (is_readable(__DIR__ . '/../../../../vendor/shopware/platform/src/Core/TestBootstrapper.php')) {
// from Shopware root vendor dir
require __DIR__ . '/../../../../vendor/shopware/platform/src/Core/TestBootstrapper.php';
} elseif (is_readable(__DIR__ . '/../../../../vendor/shopware/core/TestBootstrapper.php')) {
// from Shopware root vendor dir
require __DIR__ . '/../../../../vendor/shopware/core/TestBootstrapper.php';
} else {
throw new Exception('TestBootstrapper not found. Please install Shopware root dependencies.');
}
$classLoader = (new TestBootstrapper())
->setProjectDir($_SERVER['PROJECT_ROOT'] ?? dirname(__DIR__, 4))
->setLoadEnvFile(true)
->setForceInstallPlugins(true)
->addCallingPlugin()
->bootstrap()
->getClassLoader();
$pluginComposerDir = realpath(__DIR__ . '/..');
$pluginComposerJson = json_decode(file_get_contents($pluginComposerDir . '/composer.json'));
foreach (['autoload', 'autoload-dev'] as $loader) {
if (is_object($pluginComposerJson->$loader) && is_object($pluginComposerJson->$loader->{'psr-4'})) {
foreach ($pluginComposerJson->$loader->{'psr-4'} as $namespace => $path) {
$classLoader->addPsr4($namespace, $pluginComposerDir . '/' . $path);
}
}
}
return $classLoader;
Edit: adjusted tests/TestBootstrap.php to load TestBootrapper class from Shopware root.
I hate to add more to the noise of "autoload isn't working!!!!!", but I can't seem to get this problem figured out, and I figured getting some fresh eyes on it would get the problem in a lot less time. Here is my index.php file:
<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';
require_once 'model/PageNav.php';
use ShinePHP\{Crud, CrudException, EasyHttp, EasyHttpException, HandleData, HandleDataException};
// ALWAYS serve over encrypted channels
try {
EasyHttp::checkHttps();
} catch (EasyHttpException $ex) {
echo $ex;
}
try {
// check if it's a GET request, if it is, serve page, if not, do nothing
if (EasyHttp::isRequestMethod('GET')) {
$Page = new PageNav('Home', 'view/home.php');
$Page->buildPage();
exit;
}
}
catch (EasyHttpException $ex) {
echo $ex;
}
So obviously I am using a package from composer called ShinePHP (it's one I've made, and I'm still working on the documentation, so I'm just using it for my own projects at the moment, composer just makes package management so easy!)
ANYWAYS...because I'm writing this question, I'm obviously getting the following error:
Fatal error: Uncaught Error: Class 'ShinePHP\EasyHttp' not found in /Applications/XAMPP/xamppfiles/htdocs/KRTY/src/index.php:11 Stack trace: #0 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/KRTY/src/index.php on line 11
Now, I haven't manually touched the composer.json file, so here it is:
{
"require": {
"adammcgurk/shine-php": "~0.0.1"
},
"autoload": {
"psr-4": {
"ShinePHP\\": "src/"
}
}
}
I'm not getting any errors on requiring the vendor/autoload.php file (and I've tried changing the path to something that doesn't exist like vendor/alkdjfladksf/autoload.php and it throws an error how it should), I'm running PHP version 7.2.7 on XAMPP on Mac OS Mojave. Here is the directory structure, the highlighted index.php file is the one with the code above:
And here is the output of composer dump-autoload -o:
Generating optimized autoload files
And so...to add more to the fire of this question on Stack...How can I get composer to autoload my ShinePHP namespace with the classes as shown in the code?
This dependency does not have any autoloading rules, so Composer does not know where to find ShinePHP\EasyHttp class. You need to add autoloading configuration in composer.json of shine-php package:
"autoload": {
"psr-4": {
"ShinePHP\\": "src/"
}
},
I'm creating a composer installable project inside vendor.
This is my service provider file,
<?php
namespace vimuths123\gitpack;
use Illuminate\Support\ServiceProvider;
class GitpackServiceProvider extends ServiceProvider {
public function register() {
$this->app->bind('gitpack', function ($app) {
return new Gitpack;
});
}
public function boot() {
// loading the routes file
require __DIR__ . '/Http/routes.php';
// define the path for the view files
$this->loadViewsFrom(__DIR__ . '/../views', 'gitpack');
}
}
This is the structure,
vendor
|
vimuths123
|-gitpack
|-src
| |-GitpackServiceProvider.php
|
|-composer.json
I already added my service provider in app/config.php
vimuths123\gitpack\GitpackServiceProvider::class,
and my root composer.json I have following code.
"psr-4": {
"App\\": "app/",
"vimuths123\\gitpack\\" : "vendor/vimuths123/gitpack/src"
}
This is my package composer file,
{
"name": "vimuths123/gitpack",
"autoload": {
"psr-4" : {
"vimuths123\\gitpack\\" : "src"
}
},
"require": {
"composer/installers": "~1.2"
}
}
but all I'm getting is this error,
Class 'vimuths123\gitpack\GitpackServiceProvider' not found
It would be great help someone can help me on this.
You should not put any files into vendor/ by hand. If you are developing a library it must be composer installable library (which once installed end up in vendor/.
Your composer.json seems wrong, especially vendor/vimuths123/gitpack/src name space in psr4. This's smells from a mile as I'd bet you not using vendor/vimuths123/gitpack/src namespace.
Finally, after adding new class you should update class loader to let it know about that:
composer dumpautoload
which solves most of problems with "cannot find my class" issues.
EDIT
It seems your problems are in your library package, not the project using it. From comments it looks that you need to edit your package's composer.json. Assuming package is using vimuths123\gitpack namespace (note, namespace does NOT have to be the same as package name - these are two different things) and its sources sit in src subfolder (so it would be <project>/vendor/vimuths123/gitpack/src) then I'd rework autoload section to look like this:
"autoload": {
"psr-4" : {
"vimuths123\\gitpack\\" : "src"
}
}
and then composer dumpautoload.
Run the following artisan command:
php artisan optimize
Then see if the class can be found by Laravel.
I did my best to find a question/answer that applied, but I don't think I understand enough about the autoloader to recognize a suitable answer.
I have a package with the following composer.json:
{
"name": "Pva_agent",
"type":"library",
"description" : "query the pva agent",
"version":"0.1b",
"authors" : [
{
"name":"Ed Greenberg",
"email":"ed#precisionpros.com"
}
],
"minimum-stability":"dev",
"require": {},
"autoload": {
"psr-0": {
"Pva_agent": "."
}
}
}
My directory structure after composer installation of the package:
.
./vendor
./vendor/autoload.php
./vendor/Pva_agent
./vendor/Pva_agent/Agent.php
./vendor/Pva_agent/composer.json
./vendor/Pva_agent/.gitignore
./vendor/composer
./vendor/composer/autoload_psr4.php
./vendor/composer/autoload_real.php
./vendor/composer/autoload_classmap.php
./vendor/composer/autoload_namespaces.php
./vendor/composer/installed.json
./vendor/composer/autoload_static.php
./vendor/composer/ClassLoader.php
./vendor/composer/LICENSE
./composer.lock
./composer.json
./test_pva_agent.php
My test program:
<?php
require_once('vendor/autoload.php');
use Pva_agent\Agent;
$agent = new Agent();
My result:
edg#arthur pva_project $ php test_pva_agent.php
PHP Fatal error: Class 'Pva_agent\Agent' not found in /home/edg/PhpstormProjects/pva_project/test_pva_agent.php on line 6
PHP Stack trace:
PHP 1. {main}() /home/edg/PhpstormProjects/pva_project/test_pva_agent.php:0
edg#arthur pva_project $
I didn't think I needed the 'use' statement, since the autoloader should find the class, right?
Can somebody tell me where the problem lies?
Thanks,
Ed Greenberg
Your Pva_agent library should not sit in the vendor/ directory. This directory should contain only auto-generated data from Composer. This directory is usually not stored in VCS.
You should consider refactoring your directory structure to something similar to this one:
.
|____composer.json
|____composer.lock
|____src
| |____Pva_agent
|____vendor
Your library functionality should be added to src/Pva_agent directory.
Consider to use PSR-4 instead of PSR-0 for autoload functionality, as there is no need to regenerate the autoloader when you add classes. dump-autoloader has to be run in case of PSR-0 after adding classed.
For the directory structure above and the PSR-4 autoloader your composer.json autoload section should look similar to this one:
"autoload": {
"psr-4": { "Pva_agent\\": "src/Pva_agent" }
}
Your library should be auto loaded after this. Your auto-loaded library will be registered under the Pva_agent namespace.
Hello guys i have problem with autoloading my class with composer. On Linux all work perfect, but now my boss change env and set Windows. All this work on linux but windows show newbie fatal error:
Fatal error: Class 'AbstractController' not found in
D:\xampp\htdocs\ikacFw\frontController.php on line 7
Common to see my composer.json and stucture for better picture on problem.
Stucture is :
frontController.php
-- vendor
----- Doctrine
----- Ikac
--------- Components
---------- Mvc
------------- Controller
Am trying to load all data from vendor directory.
Composer.json
{
"autoload": {
"psr-0": {
"vendor": ""
}
}
}
Also new component i add manual. Like this :
$loader = require_once 'vendor/autoload.php';
$loader->add('vendor', "Ikac");
Okay next when i try to call :
<?php
require_once 'vendor/autoload.php';
use Ikac\Mvc\Controller;
$a = new AbstractController();
I get error "not found".
My class AbstractController contain defined namespace but dont work again. Like test i do this:
<?php
//vendor/Ikac/Mvc/Controller/AbstractController.php
namespace Ikac\Mvc\Controller;
class AbstractController {
function __construct() {
echo __CLASS__;
}
}
?>
I do from cmd composer dump-autoload, install, but dont work. All this perfect work on linux but here wont. Any idea how to fix this or where i do mistake.
Thanks guys!
SLOVED:
{
"autoload": {
"psr-0": {
"": "vendor/"
}
}
}
Well you should do
<?php
require_once 'vendor/autoload.php';
use Ikac\Mvc\Controller\AbstractController;
$a = new AbstractController();
Your autoloading declaration is wrong.
You will NEVER ever need to include the vendor folder in any autoloading. The vendor folder will contain the autoloading for both all dependencies, and - if configured - for your own classes as well.
You can use Composer to create autoloading for your own classes. Just include the correct info. But from your current info I cannot deduct what would be correct.