How to autoload from root namespace? - php

Trying the following config to load my models from root namespace failed. any alternative?
"autoload": {
"psr-4": {
"\\": "app/Models"
}
},
The following works but I have to run dumpautoload each time I create a new class.
"classmap": [
"app/Models"
],
Any suggestion?

Instead of "\\", you should map "" to "app/Models". Quoting from composer docs:
If you want to have a fallback directory where any namespace will be
looked for, you can use an empty prefix like:
{
"autoload": {
"psr-4": { "": "src/" }
}
}
So, in your case:
{
"autoload": {
"psr-4": {
"": "app/Models"
}
}
}

Related

Creating composer package for Codeigniter 4

I am trying to create my first composer package for Codeigniter 4. However, I always get an error Class 'Myapp\Settings\Greet' not found. I'm totally lost.
I created a folder inside the ThirdParty folder named myapp-settings. Inside of that folder is another folder called src and composer.json.
Here's the content of that composer.json
{
"name": "myapp/settings",
"description": ".",
"license": "MIT",
"minimum-stability": "dev",
"autoload": {
"psr-4": {
"Myapp\\Settings\\": "src"
}
},
"require": {}
}
I created a test file inside the src folder named Greet.php
<?php namespace Myapp\Settings;
class Greet
{
public function hello()
{
return 'Hey, there!';
}
}
On codeigniter's App\Config\Autoload.php
public $psr4 = [
'Myapp\Settings' => APPPATH . 'ThirdParty/myapp-settings/src'
];
Then on codeigniter's default controller I called it.
<?php namespace App\Controllers;
use Myapp\Settings\Greet;
class Home extends BaseController
{
public function index()
{
$h = new Greet();
echo $h->hello();
}
//--------------------------------------------------------------------
}
Once I run it I got an error Class 'Myapp\Settings\Greet' not found. APPPATH\Controllers\Home.php at line 9. How can I fix this?
Instead of editing the codeigniter's app/Config/Autoload.php, revert it and add these lines to the project composer.json:
"repositories": [
{
"type": "path",
"url": "app/ThirdParty/myapp-settings"
}
],
// "require": {
Then run composer require myapp/settings
Since I have also stuck at this problem, a GitHub repository is created just for it. You might check and clone, watch the commits to understand the steps.

Laravel cannot declare class because the name is already in use

Following this blog post I successfully implemented Class-based factories in Laravel.
Initially I put my ModelFactorys in app/some/folder. Everything was totally fine. But I want them in database/factories/classbased, and then this error started;
PHP Fatal error: Cannot declare class Factories\ClassBased\GroupFactory, because the name is already in use in ..root/project/database/factories/classbased/GroupFactory.php on line 18
I have had a good look on SOF and elsewhere about this error, but all the answers seem to be about different reasons/ I can't transpose the answers given to my situation.
I have tried renaming my classes to something totally unique (as ModelFactory is already a naming format used by Laravel for its standard factories) but I still got the same error. My custom classes seem to be re-declaring and I don't know why.
This is what I have for my custom class:
<?php
// database/factories/classbased/GroupFactory.php
namespace Factories\ClassBased;
class GroupFactory
{
// stuff //
public function facilitatedBy(TeamMember $teamMember)
{
$this->facilitator = $teamMember;
return $this;
}
This is what I have in my test:
<?php
namespace Tests\Feature;
use XYZ;
use Facades\Factories\ClassBased\GroupFactory;
class ClassBasedGroupFactoryTest extends TestCase
{
use RefreshDatabase, SetUpRolesAndPermissions, WithFaker;
public function setUp() : void
{
parent::setUp();
$this->setUpRolesAndPermissions();
}
/** #test */
public function it_can_set_the_facilitator()
{
$facilitator = $this->createTeamMemberWithRoleOf('facilitator');
$group = GroupFactory::facilitatedBy($facilitator)->create();
$this->assertEquals($facilitator->id, $group->facilitator->id);
}
/** #test */
public function another_test()
{
$x = 'y';
$group = GroupFactory::someThing($x)->create();
$this->assertEquals($x, $group->theThing);
}
And I have this in my composer.json:
"autoload": {
"files": [
// files
],
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories",
"database/factories/classbased"
]
},
I would expect to be able to use the class without issue, as I did when it was in the App namespace. But when I refactored to this then the errors started.
What do I need to do to fix this?
I think that the issue is not existing anymore, but I'm adding a possible solution for those who might stumble across this thread.
Use a psr-4 autoloader inside composer.json and put the factories on same level and not in a subdirectory of factories.
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Classbased\\": "database/classbased/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
Update your files to reflect the proper namespace and directory structure.
<?php // database/classbased/GroupFactory.php
namespace Factories\ClassBased;
class GroupFactory {
Sidenote: I'm still puzzled why using a subdirectory inside factories/ was not working for me.

Slim3 PSR-4 autoloader

I am writing Slim3 API, for some reason slim is not loading namespace defined in composer.
Here is the project structure.
FolderStruc:
projectApi
- composer.json
- src
- public
- index.php
- ProjectName
- Api
- Controllers
- Entities
- Commands
My composer file packages and PSR-4 autoloader settings.
composer.json
{
"require": {
"slim/slim": "^3.0",
"symfony/yaml": "3.1",
"symfony/console": "3.1",
"symfony/process": "3.1",
"doctrine/orm": "^2.5",
"doctrine/doctrine-bundle": "^1.6",
"doctrine/doctrine-cache-bundle": "^1.2",
"sabre/xml": "1.1.0",
"php-di/php-di": "#dev",
"php-amqplib/php-amqplib": "#dev",
"ramsey/uuid": "dev-master",
"monolog/monolog": "~1.15#dev",
"predis/predis": "~1.0.1",
"spipu/html2pdf": "^4.5",
"iio/libmergepdf": "~3.0"
},
"minimum-stability": "dev",
"autoload": {
"psr-4": {
"src\\ProjectName\\": "src/ProjectName/"
}
},
"autoload-dev": {
"psr-4": { "src\\ProjectName\\Tests\\": "tests" }
}
}
index.php
CategoryController
namespace ProjectName\Api\Controllers;
class CategoryController
{
/**
* #param \Slim\App $app
* #return array
*/
public function index(\Slim\App $app)
{
return ['Cats', 'Cats2', 'Cats3'];
}
}
** routes.php **
$app->get('/v1/category/list', function (Request $request, Response $response) {
$response = $response->withHeader('Content-type', 'application/json');
$categoryCtrl = new \ProjectName\Api\Controllers\CategoryController();
});
Slim fails to load namespace \ProjectName\Api\Controllers\CategoryController
any idea where and what is going wrong?
Best Regards
Danyal
You have incorrect autoloader definitions in your composer.json file.
The pattern is:
"psr-4": {
"Namespace\\Prefix\\": "/path/to/source/root"
}
So in your case it probably should be:
"autoload": {
"psr-4": {
"ProjectName\\": "src/ProjectName/"
}
},
"autoload-dev": {
"psr-4": { "ProjectName\\Tests\\": "tests/" }
}
autoload-dev definition is assuming there's a tests directory under project root path, which is not mentioned in your question.

Composer - unable to autoload files

I have a simple composer project on GitHub with the directory structure as:
/--
-composer.json
-lib/ComposerTest.php
with the ComposerTest.php file as:
namespace lib;
class ComposerTest{
public function doTest(){
return "This class was loaded from Composer\n";
}
}
and composer.json as:
{
"name":"sc/composerTest",
"autoload":{
"psr-0":{
"lib":"./"
}
}
}
Using the following composer.json file, I'm able to include the GitHub project into my vendor folder, but cannot get it to autoload.
{
"description" : "The CodeIgniter Application with Composer",
"require": {
"php": ">=5.3.2",
"codeigniter/framework": "3.1.*",
"kriswallsmith/buzz":"*",
"maltyxx/bower": "^1.0",
"sc/composerTest":"dev-master"
},
"require-dev": {
"mikey179/vfsStream": "1.1.*"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/sc/composerTest.git"
}
]
}
Can someone advise?
Edit: ComposerTest Controller
class ComposerTest extends CI_Controller
{
public function index()
{
$composerTest = new ComposerTest();
echo $composerTest->doTest();
}
}

Laravel 5 steam condenser

Composer.json
"autoload": {
"classmap": [
"database"
],
"files": [
"vendor/koraktor/steam-condenser/lib/steam-condenser.php"
],
"psr-4": {
"App\\": "app/"
}
},
HomeController
public function index()
{
$server = new SourceServer('80.67.11.46:27025');
try {
$server->rconAuth('abc123');
echo $server->rconExec('status');
}
catch(RCONNoAuthException $e) {
trigger_error('Could not authenticate with the game server.',
E_USER_ERROR);
}
}
I have updated the composer after adding, dump-autoload and tried all the solutions i can find with namespaces and so on.
But can't still use the steam condenser classes, any solution for this ?
The error Class 'App\Http\Controllers\SourceServer' not found denotes the fact that you're inside the App\Http\Controllers namespace and as such it will try to find the SourceServer class within that namespace. Prepend \ to your class name to call it in a global context:
$server = new \SourceServer('80.67.11.46:27025');
Or add this after the namespace declaration at the top of your controller:
use SourceServer;
And remove the class mapping from composer.json because it's not needed. You can read up more on how namespaces work in the PHP Namespaces Documentation.

Categories