when reading here you will see facades are not really facades
why does laravel's facade behave like a singleton?
all the methods on Facades are static anyway (go look yourself in Illuminate\Support\Facades)
and some aliases actually are just that, normal classes for example
'Arr' => Illuminate\Support\Arr::class,
whats the point of it being facades?
Why is laravel mainly using Facades instead of singletons?
Facades ARE singletons because of the way they're implemented.
First, let's define some of the terms we're using:
Facade can refer to two things:
Laravel's Facades, a tool used for developer convenience and an alternative to dependency injection
The facade design pattern. Laravel's Facades are not an implementation of the facade design pattern. This is a common point of confusion for those new to Laravel but are familiar with the facade design pattern. Laravel's Facades are better thought of as static proxies to a service within Laravel's container.
Singleton is a creational design pattern that lets you ensure that a class has only one instance, while providing a global access point to this instance. (Source)
These definitions are not mutually exclusive. Something can be a facade and a singleton (whether or not they should be both is a different conversation).
Laravel's Facades are singletons in two ways: the abstract Facade class, and Laravel's IoC Container.
The abstract Facade class - the parent of all individual Facades - is the primary reason Facades act as singletons. When a Facade is called, it resolves its underlying class from Laravel's container and saves it to a local static property. Subsequent calls will refer to the local property value, rather than resolving from the container again.
Laravel's Inversion of Control Container is another way that a Facade can reference a singleton object. When you bind a service to the container, you can use Container::singleton() to ensure that a service always resolves to the same instance when retrieved.
I hope that clarifies that something can be a singleton and a facade simultaneously.
and some aliases actually are just that, normal classes for example
An alias in this context is just a call to PHP's class_alias(), and is a way of making Facades and other classes easier to use by minimizing the fully-qualified class name (namespace + class name). Rather than needing to use Illuminate\Support\Arr;, you can just use Arr; or \Arr::get() in your code without the import. This is particularly useful within Blade templates. These aliases are useful for but not limited to Facades.
if all functions are static, why are the helper functions like session() all working with -> e.g. config()->set() vs config()::set()when the facade doesConfig::set()`?
Just a difference in purpose and implementation. A Facade is a proxy - all interaction happens with the Facade itself, but it proxies requests to the underlying service. The helper functions don't proxy any calls, they only return the service retrieved from the container.
// Only interacts with the Facade class.
// set() is proxied via the magic __callStatic() method.
Config::set();
// config() returns an instance of the Config Repository class.
// Subsequent calls are directly on that instance.
// No magic methods used.
config()->set();
Facades also come with some mocking and testing utilities that may make them a better solution, depending on your testing needs.
Related
I am a beginner starting out in laravel 5.2 and I think these concepts below should be explained more straight forward than just reading documentation.
Service Providers
Service Container
Contracts
Facades
I think a good explanation and examples that can really help beginners understand how these 4 concepts fit together in the framework.
Service provider :
The so called service providers are the heartbeat of your Laravel application. They are the central element of the initialization process where all the relevant and required code is loaded by PHP. This includes all the essentials from the framework itself, but also any own and custom code you need to load.
Inversion of Control, or IoC :
Can't be explained easly (i only have few ideas about this im not a pro)
Facades :
The Facade pattern is a software design pattern which is often used in object oriented programming. A facade is, in fact, a class wrapping a complex library to provide a simpler and more readable interface to it. The Facade pattern can also be used to provide a unified and well-designed API to a group of complex and poorly designed APIs.
A Laravel facade is a class which provides a static-like interface to services inside the container. These facades, according to the documentation, serve as a proxy for accessing the underlying implementation of the container’s services.
MORE
Contracts :
LARACASTS FREE VIDEO
I know this is not enough! what you are asking is complicated stuff a single answer can't be enough
Ok, so first I agree with the others that laracasts is an amazing resource, that will really go into greater detail and break things down very simply.
That being said, the brief overview is as follows:
Service Container (IoC container) is a laravel core process that allows you to load objects with their dependencies gracefully. For example, If I have a controller method like this:
public function update(Request $request, $id)
{
...
}
IoC container is smart enough to resolve the Request and load up all the dependencies associated with the Request class to make sure it gets instantiated properly.
It also allows you to instantiate classes without having to fully pass along all the dependencies as follows:
class ProductRepo(Product $product)
{
public function get($id)
{
...
}
}
I can reference this class without loading it with dependency injection as follows: (make sure to pass in full namespace)
app('App\ProductRepo')->get($id);
This allows me to not have to pass in a Product Object, Laravel is smart enough to resolve the Product object because the IoC container is doing the magic behind the scenes.
Service Providers are a place for you to lace in custom behavior when booting up or instantiating a class. For example, Laravel by default uses a class called the EventServiceProvider. This class's job is to configure the Event system in Laravel to make sure to include all the custom event listeners you create. So if I wanted to make sure that when the EventDispatcher is being loaded up, it brings in all the necessary dependencies.
Contracts are really simple. They are just an allusion to php object oriented concept of Interfaces. This concept states that there are classes that establish rules. For Example:
interface SearchableInterface
{
public function search($data);
}
class BinarySearch implements SearchableInterface
{
public function search($data)
{
...
}
}
This states that any class that implements the SearchableInterface, must have a function search that accepts one parameter. This creates a 'contract' that any classes that implement the SearchableInterface will have to have this function, or the application will throw an error.
This is great for using interchangeable pieces (siblings) and not having to worry that the class is missing a function you need.
Last but not least is the Facade. I love facades. In a nutshell all this is doing is creating a static representation of a class that was not defined statically. So lets say I have a class that will get a document from S3.
class S3
{
public function get($file)
{
...
}
}
Without a facade you would first have to instantiate and then call get on the class in order to get something from S3.
$s3 = new S3;
$s3->get('myAwesomeFile');
Laravel allows you to easily register Facades so that you can just use this statically for readability and convenience.
S3::get('MyAwesomeFile');
All of this has been an over-simplification of each concept, but goes into some detail about some of the basics of each concept. Hope this helps!
I know early versions of Grails used prototype scope for controllers because actions were all closures at that time.
I know that the current version documentation recommends singleton scoped controllers for controllers that use methods as actions.
From the following post it seems that methods and singleton scope are more desirable or recommended, but it's not clear why.
ttp://grails.1312388.n4.nabble.com/Default-scope-for-controllers-doc-td4657986.html
We have a large project that uses prototype scoped controllers with actions as methods. Changing to the recommended controller scope involves risk and retesting, and removing any non-singleton friendly state from existing controllers.
I'd like to know why does Grails recommend singleton scope for method as actions controllers? Is it just because that's more common and similar to Spring MVC, and avoids confusion, or is there an opportunity for performance improvement, or what? What do I gain if I make the switch to singleton controllers? What is the cost if I don't make the switch?
I haven't worked much with Rails, but (at least in the versions I played with, things may be different now) the controller is the model, containing the data to be rendered by the view. During request handling you store values in controller instance fields before handing off processing to view renderers. So there it makes sense to create a new controller instance for each request so they're distinct.
Grails was inspired by Rails and uses several of its conventions, most famously convention-over-configuration. But the ability to use the controller as the model was also added as a feature, although it wasn't well documented and I doubt many used it.
The typical way a controller action works when using a GSP to render the response (as opposed to forwarding or redirecting, or rendering directly in the controller, e.g. with render foo as JSON) is to return a Map with one or more key/value pairs from the action, and often the return keyword is omitted since it's optional in Groovy:
class MyController {
def someAction() {
def theUser = ...
def theOtherObject = ...
[user: theUser, other: theOtherObject]
}
}
Here the model map has two entries, one keyed by user and the other keyed by other, and those will be the variable names used in the GSP to access the data.
But what most people don't know is that you could also do it like this:
class MyController {
def user
def other
def someAction() {
user = ...
other = ...
}
}
In this case a model map isn't returned from the action, so Grails would populate the model from all properties of the controller class, and in this case the same GSP would work for both approaches since the variable names in the second approach are the same as the map keys in the first.
The option to make controllers singletons was added in 2.0 (technically 1.4 before it was renamed to 2.0, see this JIRA issue) and we also added support for methods as actions in addition to retaining support for closures. The original assumption was that using closures would enable some interesting features, but that never happened. Using methods is more natural since you can override them in subclasses, unlike closures which are just class-scope fields.
As part of the 2.0 rework we removed that Rails-inspired feature on the assumption that since it was essentially undocumented, that the impact on the few odd apps that used the feature wouldn't be significant. I don't recall anyone ever complaining about the loss of that feature.
Although controller classes are typically readily garbage-collectible and creating an instance per request doesn't affect much, it's rare to need per-request state in a controller, so singletons usually make more sense. The default prototype scope was left for backwards compatibility but it's easy to change the default with a Config.groovy property (and the file generated by the create-app script does this).
Although each request does get a new request and response, and if sessions are used each user will have their own, but those are not instance fields of the controllers. They look like they are because we can access request, response, session, params, etc. inside of actions, but those are actually the property access forms of the getRequest(), getResponse(), getSession(), and getParams() methods that are mixed into all controllers during compilation by AST transforms. The methods access their objects not as class fields but via ThreadLocals, so there is per-request state but it's not stored in the controller instance.
I don't remember if there was much in the way of benchmarking to compare using methods versus closures, but Lari Hotari probably did some. If there was a difference it was probably not significant. You could test this in your own application by converting just one or a few controllers and doing before and after tests. If the performance, scaling, and memory differences aren't significant between the two approaches you'll probably be safe staying with prototype score and/or closures. If there is a difference and you don't have instance fields in your controllers, then it'll probably be worth the effort to convert to singletons and methods.
If you do have instance fields they can probably be converted to request attributes - request.foo = 42 is a metaclass shortcut for request.setAttribute('foo', 42), so you could store per-request data safely there instead.
I have a class called Awesome and have used the ServiceProvider and the Facade to register it to the app. Now I can use it as Awesome::Things().
I want to add constants to this class, so I tried
<?php namespace Helper\Awesome;
class Awesome()
{
public static $MOVIE = 'I love the Lego Movie!";
}
but when I call Awesome::$MOVIE, I get Access to undeclared static property: Helper\\Aesome\\Facades\\AwesomeFacade::$MOVIE
Can someone help?
The short version is -- you don't really want to do that. Laravel facades aren't mean to be used like normal classes, and if your application uses them that way you'll likely confuse future developers.
Warning out of the way. When you create a "facade" in Laravel, you're actually creating a class alias. When you added Awesome to the alias list in app/config/app.php, at some point code like the following ran
class_alias('Helper\Aesome\Facades\AwesomeFacade','Awesome');
That means whenever you use a global non-namespaced class Awesome, PHP substitutes Helper\Aesome\Facades\AwesomeFacade. If you wanted to add constants, you'd need to add them to this class.
Laravel's able to pass through methods because of the base Facade class implements a __callStatic method that passes on your call to the actual service implementation object. Facades don't pass on static constant access. Additionally, PHP does not (appear to?) have similar magic methods for passing along requests for constants.
If you're curious about the in depth version of this answer, I'm currently writing a series on Laravel's object system, including some in-depth information about the facade implementation.
I’ve created a workbench package in Laravel 4, which is name-spaced and has two directories: Models and Contexts. Somehow, Laravel is loading my models in my Models directory (I have a model in there called User), however, it doesn’t know about my classes in the Contexts directory.
I want to be able to use my context classes in my app’s controllers without specifying the whole namespace, so I thought I’d add them to Laravel’s IoC container. However, it seems I need to create a façade class for each class I wish to add to the container. This isn’t desirable if I have dozens of context classes, as it would mean creating an equal amount of façade classes too.
Is there a way in Laravel to bulk-add classes to its IoC container?
if you want to use one term facades for your classes the laravel way (e.g. MyModel::someAction()) then you have to create your facades. but i'd advise not to do so for so many classes.
if your classes inside contexts folder aren't found then you should check your composer.json file under the autoload entry or do a composer dump-autoload -o.
I'd just DI the classes within the constructor of the class that uses them, so you end up using $this->myService->someAction().
This should answer both Laravel 4 and 5.
First, you need to use the bind method Illuminate\Foundation\Application class, which serves to register binding in the service container. In the Laravel documentation you will find plenty of examples how to do that, but only for a single binding.
If you take a look a the implementation of bind method here or just the definition here, you will notice that this method accepts a string|array. This means you can provide multiple bindings as an array and register all of them in the container with their fully qualified class names. Something like this:
$this->app->bind(['\App\Acme\Service1', '\App\Acme\Service2', '\App\Acme\Service3', ...]
Having this in mind, you can easily get the classes in one namespace (directory) with a reflection, put them in array and use the above method to register them.
Revisiting this question some time later, I think the appropriate solution would be to autoload the classes using my package’s composer.json file, and then import classes using it’s FQN in controllers and other classes:
<?php
use Vendor\Package\Contexts\ContextClass;
class Laravel4Controller extends BaseController {
protected $context;
public function __construct(ContextClass $context) {
$this->context = $context;
}
}
Could somebody explain is it possible to have potected, pivate methods in playfamewok's contolles except:
public static void method-action-name() {}
For example if I would have method like this:
protected static int doSomeWork() {}
and this method would be invoked in method-action-name() ..
public static void method-action-name() {
...
int resul = doSomeWork();
...
}
I do not want to have long action-method, so I would like to split it to smaller ones, and then reuse it in other action-methods.
I mean is it ok (from playframework's point of view) to have such method in controller side instead of having them in domain classes? In Spring Framework, we use BP (business process) beans for that, for example.
Is it ok to have such helper methods for business methods in playframework controllers ?
Added after having answer & comments:
For example if I have SearchController class then for that class would be nice to have methods like preSearch1(), preSearch2() what search() method would use, but if I move these methods (1,2) to another class then it should be class with name like SearchHelper then? in package named /src/helpers.. not very nice because they related to search too. But maybe then into /src/bp/SearchBP (bp=business-process). And then in controllers/Search i use /bp/SearchBP that use some Model object with .save() DAO methods (SearchBP can use Domain methods and Search class can use Domain methods as well)
The question here: what class ant package would be nice for those methods? (i just did watch it in examples - there alway very simple usage of controllers that use domain object that why i ask)
yes, you can. Controllers are normal classes, you can add whatever you want. It may not be recommended to clutter them with helper methods, I personally would move them to another class, but you can do what you say.
ANSWER TO EDIT:
The name of the package is "irrelevant", won't change it too much :). You can put them under controllers.support.search which would mean controllers.support is a package with helper classes and the subpackage search contains helper classes and methods related to search.
One alternative (which I like more) is to create a Service layer for that, in a "services" package. You seem to come from a Spring background, so it should come naturally to you. These services are instantiated in the controller as required, or maybe just used via static methods, and do the main business logic. That way the controller only tackles the "higher level" logic.
Another alternative is to move as much of that logic as possible into the Model (avoidid the Anemic Domain Model), and using the Model classes from the controller.
As most decisions in development, which one is better depends on your experience, possible impact/limitations in the codebase, practices in your project... anyway, you can always refactor. Just choose the one that you are more used to (it seems to be Services approach) and code away :)
Any behaviour that's complicated enough to be described as "business logic" (rather than "presentation logic") belongs in the model, not the controller. If your model does nothing but map to/from a set of database tables, then it isn't doing its job properly. Things like permissions and access control, in particular, should be enforced by the model.