Where are namespaces declared in Laravel? - 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.

Related

Autoload with composer custom classes

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

Laravel 5.4 - Access Static Method inside Controller Method

in my Laravel controller, I am trying to access a static method on a 3rd party library from a method inside the controller, but I always get the error:
"Fatal error: Class 'App\Http\Controllers\geoPHP' not found".
While on a breakpoint using VS Code, I can use the terminal and access the static method. Thoughts?
In the controller, I have the method to just get the version of the static class software:
public function parseKMLFile() {
$test = geoPHP::version();
}
In composer, in the autoload section, I have:
"autoload": {
"psr-4": {
"App\\": "app/"
},
"files": [
"app/Library/geoPHP/geoPHP.inc",
"app/Library/gpointconverter.class.php",
"app/Library/gpoint.php"
]
},
Thanks in advance
You have to be careful with namespace convention, in the controller you are in the App\Http\Controllers\ namespace, so if you want to call your custom class you have to explicit escape the controller namespace, i.e:
$test = \geoPHP::version();

Use custom folder(class) in controller

I created a new folder in the directory app which is called Services. So the directory of Services is app/Services. I want to use now a file of Services called Connection.php in a Controller app/Http/Controllers but when I try that, I get following error:
Class App\Services\Connection does not exist
I also tried to add the directory and file in my composer.json but this didn't fixed it either.
Controller:
namespace App\Services;
namespace App\Http\Controllers;
use App\Services\Connection;
use Illuminate\Http\Request;
class ExampleController extends Controller
{
protected $conn;
public function __construct(Connection $conn)
{
$this->conn = $conn;
}
Composer.json
"autoload": {
"classmap": [
"database",
"app/Services"
],
"autoload-dev": {
"classmap": [
"tests/TestCase.php",
"app/Services/Connection.php"
]
},
Edit 17.12.2016: (problem not solved yet)
Thanks for all who stick with me so long on this problem! I'm sry, if I gave too less information so I'll sum up few things that I tried.
1 => Deleted the secound namespace App\Services
2 => Added routes(or directory) to my composer.json ( like above )
3 => Used composer updated and composer dump-autoload
4 => Used use App\Services\Connection (the path to my connection class in Services, which I want to use in my ExampleController in App\Http\Controllers\ExampleController)
Connection class:
class Connection
{
//Some guzzle stuff
}
So the ExampleController looks exact as above just without the Services namespace anymore and I get exact the same error. What am I doing wrong?
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Guard;
use App\Http\Controllers\Controller;
use App\Services\Connection;
class ExampleController extends Controller
{
public function __construct(Guard $auth, Connection $conn)
{
$this->auth = $auth;
$this->conn = $conn;
}
}
Please try to use this code.
Presented this solution as a comment but to make it easier for future viewers:
The solution to this is to ensure that proper name spacing is in all files being referenced including the controller and the classes. If the namespace isn't correct it won't be able to access it.
In this case you have to make sure that the namespace for the Connection class was using App\Services as the namespace and that the controller accessed it in the same namespace of App\Services\Connection.
The error is on your namespace declaration. you are declaring two namespaces for the same class!
namespace App\Services;
namespace App\Http\Controllers;
The last one will be used.
Remove the App\Http\Controllers namespace line.
Also remember that you should import the base controller:
use App\Controllers\Controller;
Why?
When you try to use App\Services\ExampleController, composer will look for that class in the autoload paths, but since your namespace is different, it will not be able to load it.

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

Resources