In Laravel what is the difference between use User; and /User - php

i want to know the difference between
use User;
and
/User
in laravel.
In my project i see in a controller say UserController it does this
It adds
use User;
at the top of the controller and in function it uses
User::find($id);
to get query results.
And some other Controller say CompanyController it does not use
use User;
However it does this
/User::find($id);
and gets the same result.
I am confused with its usage. Which should i follow, what does each type do, can ayone please explain.

You should use use User; in combination with User::find($id);
When you have the slash in front of it you basically combine the 2 above into one.
in depth:
The User class (according to your example) appears to have no namespace, yet the file you use it in has one.
In other words, the User class is defined in the root namespace.
Normally you can use classes from the root namespace without use or /, but not when the file you use it in has a namespace.
So you will have to specify the namespace of the object you are trying to use, either with use User; or /User::
While both act identical, most developers opt to use the use variant.

Both have same behavior but different to use.
Use User;
User::all();
is basically a reference to that model class that can be used in any class to get its static methods.
/user::all();
doesn't need to call the reference, this access the model directly so both are basically same.
IN your case you are making a reference to that model class
use User;
User::find(2);
it will call model to find the matching user;
where in Company Controller you didn't use any reference to model. you're accessing that model by just '/'. laravel provides this just for ease.

Related

Laravel: why Eloquent Models methods should be invoked as fields

I am fairly new at Laravel, I have stumbled up on a very interesting concept in Laravel Eloquent Models. When I create a model lets say Tweet.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Tweet extends Model
{
use HasFactory;
public function user(){
return $this->belongsTo(User::class);
}
}
Then when I want to call the user method normally Tweet::first()->user() it dose not return the required result instead it returns (which I assume it is a closure or a reference):
Illuminate\Database\Eloquent\Relations\BelongsTo
While it works perfectly when I treated it as a filed and invoked it without the parenthesis Tweet::first()->user then I will get the actual data which is the uses's information.
Would you please let me know what is this concept, how it works, and how can we replicate it with our code.
As explained by #lagbox the difference is described in the manual under Relationship methods vs. dynamic properties
For more detail:
Tweet::first()->user() will return a query which can be used to retrieve the user (or be further refined) e.g. you can do Tweet::first()->user()->where('name', 'Bob')->first() to retrieve the user associated with the first tweet if the user's name is Bob. This makes no sense in this context but makes sense in the reverse direction where you can e.g. do User::first()->tweets()->whereDate('created_at', Carbon::today()) to get all of today's tweets.
When you do Tweet::first()->user this tries to get the relationship user if it's loaded or lazy loads it if it's not loaded. For more information on how to optimise this loading you can check Eager loading in the manual

Use keyword and New keyword in PHP

What is the difference between accessing the class through "use" keyword or declaring it as "new" plus the filepath of the class?
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
//if accessed using use keyword
use App\Entity\User;
class SampleController extends Controller
{
public function add(Request $request)
{
//if declared by "use" keyword above
$user = new User();
//if not declared by "use" keyword
$user = new \App\Entity\User();
}
}
If I'm going to use the functions of User class, the results are the same but what's the difference in their declarations?
There is no difference. By using use doesn't include anything. It just imports the specified namespace (or class) to the current scope
new \App\Entity\User(); is same as new User();
You can find more details How does the keyword "use" work in PHP and can I import classes with it?
The use keyword produces an alias for a class or a namespace.
The as keyword introduces the alias. Without as, the alias is the last component of the namespace or class path:
use App\Entity\User as OneUser;
OneUser is the same thing as \App\Entity\User and can be used instead of it everywhere in the current file.
use App\Entity\User;
Here the alias is User (the last component of App\Entity\User). It is the same as (but shorter than):
use App\Entity\User as User;
Aliased are used to write less; the code is easier to read this way.
The aliases are processed at compile time and they are visible only in the file where they are created. The mere presence of the use statement does not have any effect; it only creates a shorter name for a class or namespace but this shorter name is valid only during the compilation of the file that contains it.
The aliased class names are not expanded inside strings. During the compile time they are just text. During the runtime, 'User' is not the same as 'App\Entity\User'.
Accordingly, class_exists('User') returns FALSE but class_exists('App\Entity\User') returns TRUE.
For more insights about how PHP resolves the aliases, read the "Using namespaces: Basics" documentation page.

What namespace or facade do I have to use in Laravel to have access to my models inside a namespaced class?

I'm totally new to namespaces, and Laravel in general, so their use of Facades complicates the issue a bit for me.
I have set up a class that is namespaced:
namespace Libraries;
class UploadedFile {
}
(As there is already a Symfony class uploadedFile), and now in that class I need to use one of my models, which I can only assume rests somewhere under the Eloquent facade, yet if I:
use Eloquent;
and
use \Eloquent;
in my class, I am told my model cannot be found, yet if I prepend my model with a backslash directly:
return \Object::create(...);
It works perfectly fine. What do I need to use at the top of my namespaced file to include access to my models directly without the need for a slash?
Eloquent has nothing to do with this. You have to import your actual model Object:
use Object;

Laravel 4 Add Method to Class (IoC / Namespaces)

I'm trying to figure out how to add a method to a class in a Laravel package, so that all controllers and models that call that class can access the new method. How do I replace this class in the IoC?
This is the package in question, Angel CMS. The package is my creation, so I can modify it if we need to add aliases or anything to accomplish this.
Let's say I want to add a method to this class:
vendor/angel/core/src/models/PageModule.php
Okay, so I copy the class file to here:
app/models/PageModule.php
And then I modify the copied file, adding a namespace and the desired custom_function method:
<?php namespace MyModels;
use Eloquent;
class PageModule extends Eloquent {
protected $table = 'pages_modules';
public static function custom_function()
{
return 'It works!';
}
}
As you can see, I am using the MyModels namespace here.
Then, I run a composer dump-autoload.
Next, I open up my app/routes.php and register the binding and set up a test route:
App::bind('PageModule', function($app) {
return new \MyModels\PageModule;
});
Route::get('test-binding', function() {
return PageModule::custom_function();
});
But, when visiting the test route, I always receive the same error that the method is undefined.
What am I doing wrong here? Thank you in advance for any help.
To Clarify:
I am attempting to replace the class application-wide so that all other classes (controllers/models/etc.) that call PageModule will have access to the custom_function method. Thanks.
To be honest, I'm pretty new to all this IoC, dependency inversion/injection concept too. But I think I've gone through the same struggle before. What I would do, as much as my knowledge allows, is...
Add a constructor to src/controllers/admin/AdminPageController.php:
protected $pageModule;
public function __construct(PageModule $pageModule)
{
$this->pageModule = $pageModule;
}
Then where you did $module = new PageModule in the same file. You replace it with:
$module = $this->pageModule;
The two modifications above makes use of Laravel's IoC to allow injecting a different PageModule object into your controller, instead of strictly creating PageModule in your code.
Now at this point Laravel should know that when it constructs the AdminPageController, it should create a PageModule and inject into the controller for you.
Since your controller now expects a PageModule class, you can no longer do class PageModule extends Eloquent in your app anymore, because even though the name is the same, PHP does not think that it is! You'll need to extend it:
So let's rename your app/models/PageModule.php to app/models/CustomPageModule.php, and in the file change the class to:
class CustomPageModule extends \PageModule {
Up to this point, you also have a CustomPageModule class that is a child of your package's PageModule. All you need to do now is to let Laravel knows that if any controllers ask for PageModule, it should serve the controller with your MyModels\CustomPageModule instead.
So at the top of your app's routes.php file:
App::bind('PageModule', 'MyModels\CustomPageModule');
Your AdminPageController should now be using your CustomPageModule and can use whatever public methods that are in there!
I'm expecting to be editing this answer heavily since this will be quite a long discussion. My first try at answering above isn't the best code you can write, but I hope it takes the least amount of edit to the original code, and then we can work up from there.
Or fast track by reading up articles like http://culttt.com/2013/07/08/creating-flexible-controllers-in-laravel-4-using-repositories
You probably have a alias for the PageModule facade, you should override this alias using your class \MyModels\PageModule in your app/config/app.php file.
Be careful, it seems like you are overwriting the PageModule class instead of extending it. You should probably extend the parent class instead of Eloquent.

how to use different namespaces in a controller in laravel 4.1

What I want to do is to use different namespaces in a controller. I have a tree scheme like this:
app/
app/controllers/
app/modules/
app/modules/modulename/
app/modules/modulename/controllers/
app/modules/modulename/controllers/modulecontroller.php
app/modules/modulename/models/
app/modules/modulename/models/modulemodel.php
What I want to do is to call a model from a controller in app/controllers/ folder. Therefore I am supposed to add namespace as follows:
use App\Modules\Facebook\Controllers\Facebook;
The problem is that when I add a namespace and use App::() function at the sametime, I get the following error:
Class 'App\Modules\Modulename\Controllers\App' not found
I think it is looking the App::() function in module folder. How can I solve this problem?
if you use App inside your App\Modules\Facebook\Controllers namespace, it will be interpreted as App\Modules\Facebook\Controllers\Facebook\App class.
since you don't want to have the previous namespace, you use a \ before App like:
\App::()
or put a use statement of top the class like use App;
You probably are creating an unusual namspace scheme. It appears you are namespacing every class from your module differently. You should namespace your code within your module only, like so:
// Adding Onur to the namespace prevents any future namespace collisions.
<?php namespace Onur\Facebook;
After creating your namespace you should add all classes that are outside of your namespace that you want to use as followed.
use Eloquent, Input, Validate, Etc;
This prevents you from adding a \ in front of every class instance, making your code hard maintain and prone to errors. It also gives you a good overview on all the classes you are using in the current class.
if you say
use App\Modules\Facebook\Controllers\Facebook;
then you are supposed to use Facebook instead of App... Or donĀ“t I understand your problem correctly?
if you say
use App\Modules\Facebook\Controllers\Facebook as FacebookController;
the you can use FacebookController in your file
if you need Access to the root App, you need to to root it using a leading \
\App::make()

Categories