I like to spend time studying how frameworks are coded in attempt to better my code.
As far as I know the Scope Resolution Operator in PHP calls a function in a class as a static function, meaning that you do not have access to '$this' because the class hasn't been instantiated.
But when I started reading up how the Laravel 4 Auth works I noticed that the documentation tells you to use Auth::check() or Auth::user() to retrieve information, yet the code in those functions is using many '$this' statements.
Can anyone explain to me how they are able to retrieve the instance properties if the functions are being called as static methods?
Here is the link to the github raw file for Laravel Auth
https://raw.githubusercontent.com/illuminate/auth/master/Guard.php
Laravel uses a development pattern known as Facades and Inversion of Control (IoC) in order to take static calls to some objects (the 'Facade') and retrieve an actual instance of an object (from the IoC container) to call the method on.
Put another way, when you do Auth::check() and Auth::user() those seemingly static calls get replaced with actual object instances from within the IoC container, so Auth::check() becomes $auth->check() with $auth being derived from within the container.
This allows you to 1) Write Auth::check() instead of $auth = new Auth; $auth->check() and 2) let the IoC container do all of the dirty work around actually creating the instance you want, so if implementation details change later you don't have to rewrite any code that uses the Auth class.
See this documentation page about facades and this question about IoC in general for more information.
As a side note, the Auth facade referred to in Auth::check() et al is actually this class: https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Facades/Auth.php
It's a Fcade.
When you're calling Auth::{anything}, you're actually calling Illuminate\Support\Facades\Auth. The static method is only used as an entry point.
This is a simplified version of the Facade design pattern:
http://sourcemaking.com/design_patterns/facade/php
Related
I think i have a rough idea of what a guard does. for some reason there's not really much write-up about it online. I saw this line of code in someones middleware
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
and i don't understand what it does. i understand that there two types of inbuilt guards-web and api and web is the default guard. What does the "Guard" inside the construct do? and how does the $auth variable come into play?.
here's the pic of the full code
The Guard class is used for authentication i.e. logging a user in, checking to see if there is an authenticated user, retrieving the authenticated user, logging them out etc.
I'd say the most common way to access this information (going off the docs and various tutorials) is by using either the Auth Facade or the auth() helper function. With either approach you will have access to the same methods e.g.
auth()->user() or Auth::user() will return the current authenticated user.
auth()->id() or Auth::id() will return the current authenticated user's id.
auth()->check() or Auth::check() will tell you if the current user is logged in or not.
etc.
In either case (using auth()-> or Auth::) you're going to accessing methods on the Guard class.
Laravel also has something called the Service Container which is a way for you to be able to have dependency injection. This is essentially where you can get an instance of a class automatically without having to do something like new ClassName(). This might not seem like a big deal at first but if you have a class that needs to be passed different variable and classes to its constructor you can set this up in the container so you don't have to worry about it. Another benefit might be that you want to use the same instance of a class rather than creating a new one each time which is something that can be done with the container as well.
Now, some people prefer to use dependency injection instead of using Facades or helper functions (see here for more information). With the case in your example you're injecting the Guard class so that you can access it as a property on the class rather than using the Facade or helper function. There isn't more to it than that.
I'm a novice developer working on an existing Laravel app. I'm looking through the project and I don't see any controllers constructed anywhere but the controllers all have constructor functions.
Is this a Laravel thing or am I just missing something? Is controller instantiation handled in the routes or something? If so, is it bad practice to call a controller constructor manually?(although I can't think of a case offhand where you would want to do this)
From the docs: "The Laravel service container is used to resolve all Laravel controllers."
And: I often create a base controller in my apps, therefore I also have constructor in my extended controllers. It could also be useful to inject dependencies "properly" like shown in this example:
https://laravel.com/docs/5.2/controllers#dependency-injection-and-controllers
I see advise from a lot of people teach not to use global variable/singleton/static class and move to use of a iOC container, for example, in PHP larvel framework, it is
App::bind('foo', function($app)
{
return new FooBar;
});
$value = App::make('foo');
instead of
$value = new FooBar;
But to me, the App::bind itself is a static method and cannot be replaced easily.
So, can I say, the iOC (at least in PHP), is just remove the number of hard coded variable and minimized to one, which is the service locator, and it cannot be further reduced, right?
App::bind is not a static method, this is it's signature:
public function bind($abstract, $concrete = null, $shared = false)
(found in /vendor/laravel/framework/src/Illuminate/Container/Container.php)
Laravel uses Facades, which, while they look like they are calling a method statically, actually instantiate an object under the hood and then call an instance method on that object. While Laravel does use some static methods in it's models, the App object itself is actually a facade. You can see a list of the built in facades if you look in /vendor/laravel/framework/src/Illuminate/Support/Facades/.
So, can I say, the iOC (at least in PHP), is just remove the number of hard coded variable and minimized to one, which is the service locator, and it cannot be further reduced, right?
You are seeing this correctly, but you can actually reduce the number of hard coded variable to 0.
The problem here is not App::bind() because it's configuration. Configuration has to be coupled to some kind of system because that's where you set all the details. That's OK here.
But having App::make() all over your codebase is the problem. You want to write reusable code. You don't want your model to be coupled to Laravel for example. The fact of calling the container is called the service locator pattern (because you locate services with the IoC).
This is an anti-pattern, because, as I've said, you are coupling your code to the container.
On the other hand, there is the dependency injection pattern which is better. Dependencies are injected in your classes, but you don't care how. This is just pure PHP, completely decoupled from any container.
I invite you to read stuff on the subject, Laravel can actually be used with full dependency injection (no static calls to Facades). Here is an article on the subject: Using Dependency Injection and IoC in Laravel 4 controllers
Howard, I think the context you might be missing is why people say
global variable/singleton/static class
are "bad". The reasons you don't want global variables in your application is, relying on global state is going to lead to pain. When you're modifying values that other parts of the program also have access to, it's likely two parts of a program are going to access that same variable and unexpected "bad" things will happen. Singletons and static classes are often lumped in with global state, because they're globally available things.
So yes, your statment
is just remove the number of hard coded variable and minimized to one, which is the service locator, and it cannot be further reduced, right
is accurate, but more than that a service container (if services are being created correctly) gives you global access to a thing-to-do-a-job, but is makes it hard/impossible to use that global thing-that-does-a-job to store global application state.
I can't find how to make something like ::getInstance() like in other php frameworks to get Application (singleton) instance in symfony2
I found only sfContext::getInstance() buy it doesn't work and looks like its method from symfony1
add more info.
I have some class - abstract class Post { }. I want to get some application config, environment variables inside this class. i don't want to put all this stuff to constructor method, instead i want to call application instance and get all i want
If you take a look at web/app.php you will see that your application instance is just a global variable called kernel
$kernel = $GLOBALS['kernel'];
die(get_class($kernel));
However, the reason #san40 told you to read the documents is that you probably never actually need it for anything. SF2 is very different than SF1. So if you explained why your wanted the instance then someone might be able to suggest alternative approaches.
===================================
Looking at web/console shows that same principle for console commands except the instance is called application.
die(get_class($GLOBALS['application']))
However, using the application instance to pull environment variables and such is not recommended. If nothing else, it makes your objects completely dependent in the instance. Dependency injection is what you want. Read through the stuff in the s2 documentation.
I know that Singleton pattern is bad because it uses global state. But in most applications, you need to have a single instance of a class, like a database connection.
So I designed my Database object without using the singleton pattern but I instanciate it only once.
My question is, how can I access my object in the low level classes (deep in the object graph) without passing it all over the place?
Let's say I have an application controller which instanciates (ask a factory to instanciate it actually) a page controller which instaciates a User model which requires the database object.
Neither my app controller nor my page controller need to know about the database object but the User class does. How am I suppose to pass the object to it?
Thanks for your time!
Consider using a global container:
You register the objects that are indeed relevant to the several subsystems of the application.
You then request that container those objects.
This approach is very popular in dependency injection frameworks (see Symfony DI, Yadif).
Singleton is bad, no doubt about it.
In the case you describe, the database object is an implementation detail of the User object. The layers above need only know about the User, not the database object.
This becomes much more apparent if you hide the user object behind an interface and only consume that interface from the layers above.
So the page controller should deal only with the interface, not the concrete class that depends on the database object, but how does in create new instances? It uses an injected Abstract Factory to create instances of the interface. It can deal with any implementation of that interface, not only the one that relies on a database object.
Once more, you hide the page controller behind an interface. This means that the concrete implementation's reliance on the Abstract Factory becomes another implementation detail. The Application Controller only consumes the page controller interface.
You can keep wrapping objects like that like without ever needing to pass around instances. Only in the Composition Root do you need to wire all dependencies together.
See here for a related answer with examples in C#: Is it better to create a singleton to access unity container or pass it through the application?
The way I've always accomplished this is to implement a static getInstance function that will return a reference to the single instance of that class. As long as you make sure that the only way you access the object is through that method, you can still ensure that you only have one instance of the singleton. For example:
class deeply_nested_class {
public function some_function() {
$singleton = Singleton::getInstance();
}
}
There are two main objects involved in loading/saving a user using the database: the user and the repository.
You seem to have implemented the functionality on the User, but I think it belongs on the Repository. You should pass the user to the Repository to save it.
But, how do you get hold of the Repository? This is created once at the top level and passed into services that need it.
The construction dependency graph and the call dependency graph are not the same thing.
Given the example you outlined, you are almost there. You are already using a factory to instantiate your page controller, but your page controller is instantiating the users directly and as your User needs to know the database.
What you want to do is use a factory to instantiate your User objects. That way the factory can know about the database and can create User instances which know about it too. You will probably be better off making interfaces for all the dependencies, which will help with testing and will mean your code is nicely decoupled.
Create an IUserFactory which creates IUser implementations and pass this into your PageControllerFactory, then your ApplicationController only needs to know about the PageControllerFactory, it doesn't need to know anything about the IUserFactory or the database.
Then in your application start up you can create all of your dependencies and inject them in to each other through the constructors.