i have a Namespace Like \Project\User\ with a Class User and \Project\Menu\ with a Class Called Menu.
So if i make an instance i call new \Project\Menu\Menu() but the naming seems bad.
Mabye i call the class name Base (\Project\Menu\Base())?
Or has anyone an idea for a good naming schema .
Iam Coding in PHP.
namespaces should, mainly, resolve conflicts, for example if you are using lot of libraries.
so it is better to have less namespaces in your case
namespace MyProject
{
class User{}
}
namespace MyProject
{
class Menu{}
}
Related
I am attempting to add custom repsitories (contract and Eloquent) in Laravel.
I don't understand where to add them and how to bind with services.
Can any body show the best example for add own wn repository class and interfaces in Laravel?
Thanks in advance
Create a directory in your App folder.Like - App/Acme
Create a Repository File in Acme folder. App/Acme/CustomRepository.php and also import the name space on that Repository file.Like- namespace Acme;
Use your model. Like- use App\Models\User;
In you controller inject the CustomRepository Class.Like-
class CustomController extends Controller{
private $customRepo;
public function __construct(CustomRepository $customRepo)
{
$this->customRepo= $customRepo;
}
}
The way I like to structure my Laravel Code would be:
Models - App\Models\*
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model as BaseModel;
class Model extends BaseModel
{
//
}
Contracts - App\Repositories\Contracts\*
<?php
namespace App\Repositories\Contracts;
interface Repository
{
// All the common methods for eloquent like - all, paginate, find, where, etc...
}
Repository - App\Repositories\Db\*
<?php
namespace App\Repositories\Db;
class ExampleRepository
{
// All the CRUD related methods here...
}
Services - App\Services\*
<?php
namespace App\Services;
class ExampleService
{
// All the logic & business related methods here...
}
This is what I like to structure my code in a laravel way.
Hope this helps!
For make usage of repository pattern (if it is that what you want to say), you have two options, one of it is to implement under a self-defined namespace (let's say App\Repositories), an interface with the methods you want to use in all your repositories, maybe AbstractRepository or something like that, this one choice is painful because of the lot of code you have to write, the other choice (what I would use), is to install the following package https://github.com/andersao/l5-repository, is really useful and already have inside a lot of methods, just follow the instructions of the readme file and you will not have any issue at all implementing this pattern, hope it helps, bests! ;)
I'm trying to trick PHP into taking a class from another namespace when trying to create a specific class.
I have two class called "page", the first is in the Core namespace:
namespace Core;
class Page {...}
The second inherits from Core\Page, but adds a few things. It is in the Addons namespace.
namespace Addons;
class Page extends \Core\Page{...}
The reason I want to do this is because I want to build my system with an easy addon engine. Whenever I want, I can add a line in an XML file that tells the autoloading function to take the class in the addon namespace instead of the core namespace.
However, when I try to do this :
spl_autoload_register('loadClass');
public function loadClass(string $className)
{
if (Addon_exist_and_is_registered($className))
{
require "/Addons/$className.php";
}
else
{
require "/Core/$className.php";
}
}
$page = new \Core\Page(); <-- error here
I get an error saying that the class \Core\Page cannot be found in the file Addons\Page.php. This is normal behaviour since the class is not in the same namespace and as such, the fully qualified name cannot find the right class.
Is it possible to trick PHP into thinking that a child class in another namespace is actually the right class? I tried this for the addons class;
namespace Core;
class Page extends \Core\Page{...}
But it breaks the inheritance as you cannot inherit yourself.
Ignore that the classes have the "same name". Because they don't. One class is called Core\Page, the other is called Addons\Page. Those are their names, their fully qualified names to be exact. It's as much a difference as Foo and Bar. If you tell PHP to instantiate Core\Page, then it's going to do that; you can't "trick" it into instantiating Addons\Page, since that's an entirely different class name.
Don't try to "trick" anyone, make your system actually extensible and explicitly allow overriding of class names:
$class = 'Core\Page';
if (...) {
$class = 'Addons\Page';
}
$page = new $class;
I'm just wrapping my head around PHP namespaces and autoloading with composer. I have a question about the following code:
namespace APP\Controllers;
use APP;
use APP\Interfaces;
use APP\Lib;
class PageController
extends Lib\ActionController
implements Interfaces\ControllerInterface
{
//stuff
}
Why do I have to prepend the extends class with the sub-space with 'Lib\' when I already use the line 'use APP\Lib;'? Same goes for the interface. When I don't prepend I get an autoload error. I'm using composer to autoload and have this in my composer.json:
"autoload": {
"psr-4": {
"APP": "app/"
}
}
In app/ I have subfolders Lib, Interfaces and Controllers like so:
/app
/Controllers
/Interfaces
/Lib
I noticed that in other devs code they don't have to do this. I'm confused as to what I am doing wrong.
Thanks for the help.
You are including three namespaces:
use APP;
use APP\Interfaces;
use APP\Lib;
Now if you say just:
extends ActionController
PHP would not know if it is:
APP\ActionController or
APP\Interfaces\ActionController or
APP\Lib\ActionController
If you still wanted to extend it without Lib subspace you would need to do:
use APP\Lib\ActionController; first
use is only there to alias namespaces or class names to shorter names. It's there to avoid having to repeatedly address all classes by their fully qualified name all the time:
$a = new \Foo\Bar\Baz\Quurx();
$b = new \Foo\Bar\Baz\Quurx();
// shorter:
use Foo\Bar\Baz\Quurx;
$a = new Quurx();
$b = new Quurx();
use Foo\Bar is shorthand for use Foo\Bar as Bar. So, you're creating an alias Bar which really resolves to the full name \Foo\Bar. Since APP\Interfaces doesn't resolve to any particular interface in your case, just using implements Interfaces wouldn't mean anything. And if you just used implements ControllerInterface, it would be ambiguous which namespace that resolves to. \APP\Controllers\ControllerInterface? \APP\ControllerInterface? \APP\Lib\ControllerInterface? It's just not clear and cannot be resolved automatically.
So, what you're doing is you're shortening APP\Interfaces to just Interfaces, and then refer to APP\Interfaces\ControllerInterface by just using the shorter Interfaces\ControllerInterface. You could be doing this to make it even shorter:
use APP\Interfaces\ControllerInterface;
.. implements ControllerInterface ..
I am working on a php sdk rewrite project and the client wants to get PSR standards done. I am looking at the standards page here
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
One thing what i am not able to understand, if i use name spaces in my class do i still need to use include or require or use. I mean the whole reason of autoload beats the purpose right ?
For example, say i have a class this way,
namespace Employee\Department;
Class Department
{
//code
}
and i have another class which uses this class by extending it,
namespace Employee\community;
Class Community extends Department
{
//code
}
so does the above code make it to psr-0 standard considering that i have an autoload function exactly thats on the link above.
The second example is going to assume Department is in the Community namespace so in this case you would need a use statement. Also both of your examples would use the namespace Employee not Employee\Whatever for example lets assume the following layout:
Employee/
Community.php
Community/
Manager.php
Department.php
Department/
Manager.php
Then we would see the class/namespaces like the following
namespace Employee;
class Department {
}
///////////
namespace Employee;
class Community extends Department {
}
/////////////
namespace Employee\Department;
class Manager {
}
/////////////
namespace Employee\Community;
use Employee\Department\Manager as BaseManager;
Class Manager extends BaseManager {
}
For your understanding, autoloading works by registering the autoload function in the autoload stack via spl_autoload_register; this allows the function to be invoked whenever a new Class() statement is executed (more info).
On the other hand, the FIG standard for autoloading, PSR-0, defines how a namespace will be translated into a filename by a PSR-0 autoloader function. For example, given the namespace Vendor\Foo, the autoloader will look for the file Vendor/Foo.php having the following code
namespace Vendor;
class Foo
{
public function do()
{
echo "Foo";
}
}
Therefore, following the mandatory requirements, a PSR-0 compliant namespace resolves to the correct PHP file which could otherwise have been included using a require or include.
If I read your intentions correctly, you just need the following namespace in both code snippets:
namespace Employee;
Of course, this is not a PSR-0 namespace because there is no vendor name (unless your vendor name is 'Employee'). Anyway, using this namespace in your two code snippets will work fine.
However, if you intended to keep them in separate namespaces, then the autoloader won't figure out Department in extends Department in the second snippet. You will have to either import the namespace or explicitly specify it as so:
namespace Employee\community;
class Community extends Employee\Department\Department
{
//code
}
I imagine that you did not expect the full class names from your snippets to be Employee\Department\Department, and that is why I first suggested keeping the same namespace for your purposes.
When using the pseudo namespacing pattern of PEAR and Zend, it is common to come across class heirarchies that look like this:
Zend/
Db.php
Db/
Expr.php
Where DB.php contains a class named Zend_Db and Expr.php contains a class named Zend_Db_Expr. However, when you try to convert the old 5.2 psuedo namespacing into PHP 5.3 namespacing you are presented with a case where a namespace and a class share a name. Since the use operator can import either a namespace or a classname this leads to ambiguity.
Here's an example of an app I'm working on converting:
App/
Core.php
Core/
Autoloader.php
Here the base directory and namespace are App. In the top level of the name space is a Core class:
namespace App;
class Core { }
In the Core directory are various other core classes, some of which use the main Core. Under the pseudo namespacing pattern, this isn't a problem. But in the real namespacing pattern it creates this situation:
namespace App\Core;
use App\Core as Core; // What is this importing? Namespace or class?
class Autoloader {
public function __construct(Core $core) {}
}
Is this defined? What is actually imported here?
Simply both. It is not real import, just a hint for compiler, that every encounter of this alias in class related operations should be expanded to this declaration. In php namespace is just part of class so just think of it like this
$alias = 'Zend_Db';
$zendDB = new $alias;
$aliasExpr = $alias . '_Expr';
$expr = new $aliasExpr;