PSR-4 autoloader Fatal error: Class not found - composer-php

I have my project structure like so:
src/
├─ Model/
└─ User.php
My User.php file looks like this:
<?php
namespace Bix\Model;
class User {
And my composer.json autoloader is this:
"autoload": {
"psr-4": {
"Bix\\": "src/"
}
}
Finally my bootstrap.php is this:
use Bix\Model\User;
// PSR-4 Autoloader.
require_once "vendor/autoload.php";
However if I try and create a new User(), I get the error Fatal error: Class 'User' not found in /var/www/public/api/v1/index.php on line 8
Looking at the composer autoload_psr4.php file it looks ok:
// autoload_psr4.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname(dirname($vendorDir));
return array(
'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'KeenIO\\' => array($vendorDir . '/keen-io/keen-io/src'),
'Bix\\' => array($baseDir . '/src'),
);
Can anybody point out where I am going wrong with the above?

First of all, Linux (I'm not sure which PC you use) is case-sensitive. In your autoloading, you defined src/bix, while it is src/Bix.
But more importantly, with PSR-4, the specified namespace prefix is not included in the directory structure (to avoid directories containing just one directory). In your case, if you configure "Bix\\": "src/", a class Bix\Model\User should be located in src/Model/User.php.
EDIT: You're misunderstanding PHP namespaces. In PHP, you're not saying "import everything from Bix\Model into the global namespace for this file" with use Bix\Model;. Instead, it means: "Alias Model in this file to Bix\Model".
So you should either do:
require_once "vendor/autoload.php";
use Bix\Model;
$user = new Model\User();
or:
require_once "vendor/autoload.php";
use Bix\Model\User;
$user = new User();

Related

Upload to Dropbox not working from Laravel with Dropbox driver

I'm trying to upload a (DomPDF generated) PDF file to Dropbox with the Dropbox driver in Laravel 8. I've installed spatie/flysystem-dropbox and created a DropboxServiceProvider.php with following contents:
<?php
namespace App\Providers;
use Storage;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
use Spatie\Dropbox\Client;
use Spatie\FlysystemDropbox\DropboxAdapter;
class DropboxServiceProvider extends ServiceProvider
{
public function boot()
{
Storage::extend('dropbox', function ($app, $config) {
$client = new Client([$config['key'], $config['secret']]);
return new Filesystem(new DropboxAdapter($client));
});
}
public function register()
{
//
}
}
The service provider is also added to my config/app providers:
'providers' => [
...
App\Providers\DropboxServiceProvider::class,
...
]
In my config/filesystems I've added the dropbox driver (dropbox app key and secret are also set in .env file):
'dropbox' => [
'driver' => 'dropbox',
'key' => env('DROPBOX_APP_KEY'),
'secret' => env('DROPBOX_APP_SECRET'),
]
Now, when I try to run the following code, it returns false and the file doesn't appear in my Dropbox. When I change the disk to 'local', the file gets uploaded to my local storage.
$path = "pdf/file.pdf";
$storage_path = Storage::path($path);
$contents = file_get_contents($storage_path);
$upload = Storage::disk('dropbox')->put($path, $contents);
return $upload;
I've already tried clearing my config by running php artisan config:clear. After trying many different things, I have no idea what I'm doing wrong, so any advice will be appreciated!
The problem was not in the code, but in the permissions in my dropbox app: files.content.write wasn't enabled yet.

Lumen Cache\Store is not instantiable

I'm quite new to Laravel and Lumen, so my question may be a little simple, but I couldn't find any useful answer yet.
Lumen version is 5.1.
So I tried to create a data repository supported by a cache. Firstly I want to use FileStore, then I want to move to some more appropriate.
I tried to inject Cache repository like this:
<?php
namespace App\Repositories;
use Illuminate\Cache\Repository;
class DataRepository
{
private $cache;
public function __construct(Repository $cache)
{
$this->cache = $cache;
}
}
It seemed pretty simple to me. But when I try to use this repo in my controller, and tried to inject this repo into it, during instantiation I get the following error:
BindingResolutionException in Container.php line 749:
Target [Illuminate\Contracts\Cache\Store] is not instantiable.
I guessed the repository cannot find the matching and useable store implementation. When I tried to bind the Store to \Illumante\Cache\FileStore like this:
$this->app->bind(\Illuminate\Contracts\Cache\Store::class, \Illuminate\Cache\FileStore::class);
I got a new kind of error:
Unresolvable dependency resolving [Parameter #1 [ <required> $directory ]] in class Illuminate\Cache\FileStore
I guess I have a more complicated config issue, so I didn't want to walk through the dependency tree.
In my .env I have these:
CACHE_DRIVER=file and SESSION_DRIVER=file
In Lumen I explicitly enabled the facades, the DotEnv (and the eloquent also for my data repositories).
Dotenv::load(__DIR__.'/../');
$app = new Laravel\Lumen\Application(
realpath(__DIR__.'/../')
);
$app->withFacades();
$app->withEloquent();
I tried to add a cache.php configuration. In the bootstrap/app.php I added $app->configure('cache'); to use it with the following configs:
<?php
return [
'default' => env('CACHE_DRIVER', 'file'),
'stores' => [
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache'),
],
],
];
Could you help me, how can I bootstrap the Cache properly?
Answer
The cache implementation in Lumen is registered as:
Illuminate\Contracts\Cache\Repository
Not
Illuminate\Cache\Repository
So you may change your code to:
<?php
namespace App\Repositories;
use Illuminate\Contracts\Cache\Repository;
class DataRepository
{
private $cache;
public function __construct(Repository $cache)
{
$this->cache = $cache;
}
}
P.S You don't need to configure cache, since Lumen will configure any cache configuration automatically.
Tricks
But if you still want to use Illuminate\Cache\Repository, you may bind it first in your ServiceProvider or bootstrap/app.php file:
use Illuminate\Cache\Repository as CacheImplementation;
use Illuminate\Contracts\Cache\Repository as CacheContract;
$app->singleton(CacheImplementation::class, CacheContract::class);

Access to composer autoloaded files in laravel 5

Trying to use a non-Laravel package: https://packagist.org/packages/luceos/on-app
Edited composer.json to require it and did the composer install, update, then dump-autoload -o.
This package requires an initialization: vendor/luceos/on-app/src/OnAppInit.php
Which isn't a class and only has the one method. But it doesn't seem to be loaded when I try to bind it in a service provider. The version for the cloud is initiated in the OnAppInit.php but that isn't being done so the "version isn't supported" error comes up of course.
I know that I am missing a small detail but can't find it. Maybe in the service provider??
composer.json
"require": {
"luceos/on-app": "~3.5"
"autoload": {
"psr-4": {
"Luceos\\OnApp\\": "vendor/luceos/on-app/src/"
config/app.php
'providers' => [
'App\Providers\OnAppServiceProvider',
app/Providers/OnAppServiceProvider.php
public function register()
{
$this->app->bind('onapp', function($app)
{
$hostname = 'http://cloud';
$username = 'email#foo.com';
$password = 'api_key';
$factory = new \OnApp_Factory($hostname, $username, $password);
$setting = $factory->factory('Settings')->getList();
return $setting;
});
}
Looks like its there...
vendor/composer/autoload_files.php
$vendorDir . '/luceos/on-app/src/OnAppInit.php',
vendor/composer/autoload_psr4.php
'Luceos\\OnApp\\' => array($vendorDir . '/luceos/on-app/src'),
Regarding the Guzzle question:
Just include it in your composer.json file:
"guzzlehttp/guzzle": "~5.0"
And then just use the normal
$client = new GuzzleHttp\Client();
Just don't forget to to composer dump-autoload

Laravel 4.1 - calling View Composers class - ReflectionException class does not exist

I keep getting this error when trying to call a View Composer class: Class MyApp/Composers/HeaderComposer does not exist
/app/MyApp/Composers/HeaderComposer.php:
<?php namespace MyApp\Composers;
class HeaderComposer {
public function compose($view) {
$view->with('foo', 'foobar');
}
}
composer.json:
"psr-4": {
"MyApp\\" : "app/MyApp/"
}
routes.php:
View::composer('layouts.default', 'MyApp/Composers/HeaderComposer');
vendor/composer/autoload_psr4.php
<?php
// autoload_psr4.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'MyApp\\' => array($baseDir . '/app/MyApp'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
);
What else could I be missing?
Thanks,
Ham
Change forward slashes in
View::composer('layouts.default', 'MyApp/Composers/HeaderComposer');
to back slashes
View::composer('layouts.default', 'MyApp\Composers\HeaderComposer');
and it will work

Intergrating Zend Framework 2 and Propel

I've searched far and wide on how to intergrate propel and Zend Framework 2 however I haven't been able to come up with a solution yet.
Here is what I have so far.
Installed ZF2 Skeleton Directory
Inserted Sample Album Table Data from ZF site
My Folder Structure looks like this
--Vendor
----Propel
------album
--------autoload_classmap.php
--------models
----------map
----------om
----------Album.php
----------AlbumPeer.php
----------AlbumQuery.php
------config
--------module.config.php
------Module.php
------autoload_classmap.php
The album/autoload_classmap.php looks like this
//vendor/Propel/album/autoload_classmap.php
<?php
// Generated by ZF2's ./bin/classmap_generator.php
return array(
'AlbumTableMap' => __DIR__ . '/models/map/AlbumTableMap.php',
'BaseAlbumPeer' => __DIR__ . '/models/om/BaseAlbumPeer.php',
'BaseAlbumQuery' => __DIR__ . '/models/om/BaseAlbumQuery.php',
'BaseAlbum' => __DIR__ . '/models/om/BaseAlbum.php',
'Album' => __DIR__ . '/models/Album.php',
'AlbumPeer' => __DIR__ . '/models/AlbumPeer.php',
'AlbumQuery' => __DIR__ . '/models/AlbumQuery.php',
);
Here is the module.config.php
//vendor/Propel/config/module.config.php
<?php
return array();
Here is the Propel/autoload_classmap.php
//vendor/Propel/autoload_classmap.php
<?php
// Generated by ZF2's ./bin/classmap_generator.php
return array(
'Propel' => __DIR__ . '/runtime/lib/Propel.php',
);
and finally the Model.php file
//vendor/Propel/Module.php
<?php
namespace Propel;
class Module
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
__DIR__ . '/album/autoload_classmap.php'
)
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
For the sake of simplicity in this example I put the following code into my Controller.
//module/Application/src/Application/Controller/IndexController.php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
public function indexAction()
{
$q = new \Propel\Album();
$q->setArtist('The Who');
$q->setTitle('Tommy');
$q->save();
return new ViewModel();
}
}
The error I get is
Class 'Propel\\Album' not found
The sources I used to get to this point were
https://groups.google.com/forum/?fromgroups=#!searchin/propel-users/zend/propel-users/lsHs-jjxp68/LDrQjzik6gAJ
https://docs.google.com/viewer?a=v&pid=forums&srcid=MDU2NDIxODQyNDc0MDMyNjQ3NzUBMDY3ODcxMTYzMzg0MDA4OTU0MzgBeFpDZUM1WTZqMThKATQBAXYy
Adding Vendor Specific Module To Zend Framework 2.0
If you didn't set namespace in your XML schema, your classes should be accessible in the root namespace, so as \Album for example. If you want to have some other namespace, you shoud define it in database tag of your XML schema. And you should not use Propel namespace anyway as it is reserved for Propel itself. Your generated classes should be long to the namespace of your project.
\Propel\Album is not being found because the class map specifies Album as the class name.
I'm guessing if you added the line: namespace Propel; to each of those Propel related files the classmap generator would put the correct class names. Of course then you would need update an class names in the code that are affected.

Resources