Autoload with composer custom classes - composer-php

I'm new to composer to manage the loading of my custom classes. I'm trying to add some custom classes to the autoload but without success, I will get always a Class not found... error.
How I will setup correctly composer, where I should put the composer.json file with the psr-4 info about my custom class/classes?
Can anyone help me understand how it will work in this case?
Here is my class code snippet, I'm using some composer packages so I need to autoload them. This file is placed in it's own directory. th structure looks like this: project_root\assets\library\MyClassFolder
<?php
namespace MyNamespace;
require_once __DIR__.'/vendor/autoload.php';
use \Foo\Bar;
class MyClass {
...
}
?>
This is the code where the class need to be loaded. This file is located inside my project root folder and it's causing the error:
<?php
require_once __DIR__.'/vendor/autoload.php';
use \MyNamespace\MyClass;
if( isset($_POST['do_action']) ){
MyClass::init();
}
?>
This is the composer.json file that is in the project root:
{
"require": {
"gabordemooij/redbean": "^5.3"
},
"autoload": {
"psr-4": {
"MyNamespace\\": "assets/library/"
}
}
}

I've found a fix, I was made a mistake inside the composer.json file. I was not pointing the namespace to the classes directory. This is why I've got a Class not found... error.
the composer file now look like this:
{
"require": {
"gabordemooij/redbean": "^5.3"
},
"autoload": {
"psr-4": {
"MyNamespace\\": "assets/library/MyClassFolder/"
}
}
}
I also needed to change the require_once inside the custom classes files to point to the vendor path where reside the autoload file.
Instead of
require_once __DIR__.'/vendor/autoload.php'
Now I've
require_once dirname(__DIR__, 3).'/vendor/autoload.php'
This because the

Related

How to autoload service namespace in laravel 5.6

I have created some library services in app\Library. I used AppServiceProvider to bind that service using following code:
$this->app->bind('App\Library\Globalfunction', function ($app) {
return new Globalfunction();
});
app\Library\Globalfunction.php
<?php
namespace App\Library;
class Globalfunction {
protected $_ci;
public $siteConfig=array();
public $smtpConfig=array();
public $socialConfig=array();
public $paramConfig;
public $paramFrom;
public function test($param) {
return $param;
}
}
?>
To use this test() in controller i am including namespace using following:
use App\Library\Globalfunction;
once namespace is included i use following code:
$globalFunction = new Globalfunction();
echo $globalFunction->test('hello');
All of this code working fine but i don't want to add use App\Library\Globalfunction; in each file so is there anyway i can do that? is there any autoload file where i can put this and i can access Globalfunction?
I google solution for that and i tried several solutions like add this in composer or create package etc but it's not working so please if anyone have solution for this problem please let me know.
Maybe you can follow the same approach as Laravel?
Let me give you an example on how to achieve this.
First, create a Helpers.php file in app/Helpers.php.
You also need to autoload it.
"autoload": {
"classmap": [
"database/seeds",
"database/factories",
"database/providers"
],
"files": [
"app/Helpers.php"
],
"psr-4": {
"App\\": "app/"
}
}
Once that is done, you could define a function as such in your newly autoloaded Helpers.php:
if(! function_exists('global_function')) {
function global_function()
{
return new \App\Library\Globalfunction();
}
}
Then to use it anywhere, you can just do this.
global_function()->test('hello');
This is just a simple example. Obviously there are a lot of considerations you have to make before implementing this.
However, Laravel has a similar approach to providing global helper functions. For example:
use Illuminate\Support\Facades\Session;
// This
echo Session::get('key');
// is the same as
echo session()->get('key');

Where are namespaces declared in Laravel?

I learned in php that to be able to use a namespace, you have to declare or include first.
<?php
namespace namespace_01;
function f1()
{
echo 'this is function';
}
use namespace_01 as test_namespace;
test_namespace\f1();
?>
Almost all of laravel codes use namespaces. But where are they defined?
Example,
when I created a controller.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class controller1 extends Controller
{
//
}
where is Illuminate\Http\Request defined?
Open file from vendor/laravel/framework/src/Illuminate/Http/Request.php
There you will see the namespace declared on top as namespace Illuminate\Http; and the class name is Request
and you can see in your composer.json file
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
so all the classes inside App folder are auto loaded with composer and also the vendor files. you don't need to include files every time.
These are found in the Laravel Framework. Laravel uses composer to automatically load these packages. You can find the source in your /vendor folder, this is where composer puts the packages.

Where are Laravel 5.1 Repositories?

I was going through socialite tutorial which is created by Laravel 5 and I'm using Laravel 5.1 and I saw that there is a file in tutorial like AuthenticateUser.php in repositories folder. But repositories folder doesn't even exist in Laravel 5.1. Where I should create a file AuthenticateUser.php in Laravel 5.1?
Laravel uses composer's autoloading, so it doesn't matter where you store your files, so long as their autoloading mechanism is defined in the composer.json file. Laravel 5 apps start with this defined in their composer.json:
"psr-4": {
"App\\": "app/"
}
So if you created a directory at app/Repositories, you could create a file in it that looked like this:
<?php namespace App\Repositories;
class MyRepository {
public function doSomething() {}
}
Then you can reference it in the rest of your application like this:
<?php namespace App\Http\Controllers;
use App\Repositories\MyRepository;
use Illuminate\Routing\Controller as BaseController;
FooController {
protected $repo;
public function __construct(MyRepository $repo)
{
$this->repo = $repo;
}
public function someAction()
{
return $this->repo->doSomething();
}
}
Composer will load the file for you, so long as you've defined a mechanism for doing so.

Laravel 5 Controller from a Different namespace

I am trying to load controller that resides inside a package.
Package itself is on the root level in a folder like /packages/my/ ...
The package structure is like this:
/packages/my/framework/src/My/Controllers/PageController.php
Frist in my RouteServiceProvider:
$router->group(['namespace' => 'My\Controllers'], function($router)
{
require "...../routes.php";
});
in the composer.json in the root of laravel
"psr-4": {
"App\\": "app/",
"My\\": "packages/my/framework/src"
}
then composer dump-autoload , i can see its been added to autoload_psr4.php
the actual controller
<?php
namespace My\Controllers;
use App\Http\Controllers;
class PageController extends Controllers\Controller { .... }
But I am getting ReflectionException that the class does not exist. Obviously the routing part works, why it can't see the Controller?
Thanks!
closing my own question .. I was missing the root namespace in the psr-4 loader .. packages/my/framework/src/My

Managing Own Classes with Composer

I'm new to composer and autoloaders. I think I also lack of file organization strategies.
I'm trying to build up a new project on slimframework.
I have some classes for Slim. But I can not autoload them in my project.
/
composer.json
composer.phar
vendor
config
someapiparams.php
database.php
cache.php
general.php
public
index.php
models
libraries
Foo
Slim
Config.php
Cache.php
/composer.json:
"autoload": {
"psr-0": {
"Foo": "libraries/"
}
}
/libraries/Foo/Slim/Config.php:
<?php
class Config {
/**
* Loads a file based on $key param under ROOT . "/config",
* if not already loaded.
* Then returns an array.
*/
public static function get($key) {}
}
/libraries/Foo/Slim/Cache.php:
<?php
class Cache{
/**
* Initialize a caching engine defined in config file if not already done.
* Then runs corrensponding engine methods for getting and setting.
*/
public static function init() {
$config = Config::get("cache");
// initialize driver.
}
public static function __get($key) {}
public static function __set($key, $value, $params) {}
}
/public/index.php:
require ROOT."/vendor/autoload.php";
$app = new Slim\Slim();
var_dump(Config::get("database")); exit;
//var_dump(Foo\Slim\Config::get("database")); exit;
//var_dump(Slim\Config::get("database")); exit;
Error is Config class not found.
You have forgotten to put:
namespace Foo/Slim;
at the top of /libraries/Foo/Slim/Cache.php (or have possibly have snipped it for the code example).
If adding the namespace doesn't fix it, you should step through the code with a debugger, and see exactly what files the Composer autoloader is searching for, when it tries to load the class and fails.

Resources