Best everyone,
There is one thing in Laravel 4 I just can't understand if you create a namespace in my case cms and you want to use for instance View::make or Input::all()
laravel wil tell you it could not be found what is correct since those methods are in the global namespace and not in cms so to get it to work you can refer to it with adding a backslash before the method that will it wil user the global namespace. however i find that confusing isn't there a way to have a use or something that imports all the Input, Hash, Redirect enz.. So you could use it without adding \.
Not sure I completely follow, do you mean: using View::all() without doing \View::all() in a cms Namespaced file?
If so you can import namespaces by using the use keyword and alias them by using the as keyword
e.g.
use MyNameSpace\View; // Imports only
use MyNameSpace\View as MyView; // Imports and Aliases
class {
....
}
For more details please see http://php.net/manual/en/language.namespaces.importing.php
Related
I am trying to add the following library (link) to my Symfony project using composer.
I have run
composer require jaggedsoft/php-binance-api
without a problem but I am getting the following error when loading the page.
Attempted to load class "API" from namespace "App\Controller\Binance".
Did you forget a "use" statement for another namespace?
public function index(){
require '../vendor/autoload.php';
$api = new Binance\API("<api key>","<secret>");
}
Now i am guessing that I need to add a use statement but I am a bit stuck on what it is that I need to add.
To reiterate what I suggested in the comments (options 1 and 3 below):
The namespace of your file - although not explicitly written in your post - is:
App\Controller
without any use statement, the new Binance\API(...) is interpreted as:
App\Controller\Binance\API
which is the concatenation of App\Controller (your namespace) and Binance\API (the classname used).
which of course is not what you want to use, since this is something you tried to include from the binance package. This also explains the error message
Attempted to load class API from namespace App\Controller\Binance. Did you forget a use statement for another namespace?
which is exactly what went wrong. PHP tried to load App\Controller\Binance\API which is class API from namespace App\Controller\Binance.
Now there are A few different ways to fix this:
add use Binance; in the header of your file, then you can use new Binance\API(...)
add use Binance\API; in the header of your file, then you can use new API(...)
don't add a use statement, then you can use new \Binance\APi(...)
add use Binance as Something; in the header of your file, then you can use new Something\API(...); (aliasing the parent namespace Binance as Something may resolve name collisions)
add use Binance\API as BinanceApi; in the header of your file, then you can use new BinanceApi(...);
You decided to use option 1. Which is preferable, if the class (API in this case) isn't very expressive or unique on its own - so is option 5. However, if you use more classes from the Binance namespace, option 1 is preferable.
Option 3 will always work (and might seem preferable if any of the other options seem overkill for some reason) - you can actually get by without any use statement at all, but it can get frustrating to read and write.
Overall, all options are viable and it comes to taste which one to use. Mixing those options may lead to confusion. Inside Symfony I've mostly seen option 2 with the occasional alias (use ... as ...;), especially when using DoctrineORM annotations or when extending some Class which has the same Class name but in a different namespace:
namespace [package1];
use [package2]\[ClassName] as Base[ClassName];
class [ClassName] extends Base[ClassName] { ... }
I hope this explanation helps. The php docs for namespaces are actually helpful, when you understand the core concept of namespaces.
I used use the keyword "use" generally above the class definition. Like this:
<?php
namespace suites\plugins\content\agpaypal;
use \Codeception\Util\Fixtures;
use \Codeception\Verify;
use \Codeception\Specify;
class agpaypalTest extends \Codeception\Test\Unit
{
protected $tester;
...
But now I realised, that I have to put the line for the trait Specify into the class definition. Like this:
<?php
namespace suites\plugins\content\agpaypal;
use \Codeception\Util\Fixtures;
use \Codeception\Verify;
class agpaypalTest extends \Codeception\Test\Unit
{
use \Codeception\Specify;
protected $tester;
...
I think it is because the package \Codeception\Specify; is a trait. But I do not understand why I couldn't reuse this trait when I set the line
use \Codeception\Specify;
before the class definition?
I would be happy if someone could point me to a hint or an explanaiton that explains to me where I should use the keyword "use" the best.
In PHP, the keyword use is used in 3 cases:
As class name alias - simply declares short name for a class (must be declared outside of the class definition)
(manual: Using namespaces: Aliasing/Importing )
To add a trait to a class (must be declared inside (at the top) of the class definition)
(manual: Traits)
In anonymous function definition to pass variables inside the function
(manual: Anonymous functions)
You can not import class with use keyword. You have to use include/require statement. Even if you use some php auto loader, still autoloader will have to use either include or require internally.
The Purpose of use keyword:
Consider a case where you have two classes with same name; you'll find it strange, but when you are working with big MVC structure, this happens. So if you have two classes with same name, put them in different name spaces. Now consider when your auto loader is loading both classes (does by require), and you are about to use object of class. In this case, the compiler will get confused which class object to load among two. To help the compiler make a decision, you can use the use statement so that it can make a decision which one is going to be used on.
Here refer this
How does the keyword 'use' work
use is basically including a class in the file to use it.
There are two ways to include a class file in another file.
The most general is require or include method. Another method is using composer. Assume this Directory Structure
Project
|
|--- Folder A
| |
| |---UserRegistration.php
|
|---Example
|
|--TestUserRegistration.php
In Folder A there is UserRegistartion.php and you want to use the code in TestUserRegistration.php In UserRegistration.php It can be class, trait or Interface
Method 1.
In TestUserRegisteration.php you can include or require file UserRegistartion.php
and use it
Method 2
Using Composer. In UserRegistration.php you define namespace FolderA; as the first line of code. Then write your code as you do. So Now you want to use this file in TestUserRegistration.php you do
include vendor/autoload.php;
use FolderA\UserRegistration;
Which one is better and why?
Method 2 using composer is the best method. In method 1 wherever you want to include UserRegistration you have to find the relative path to UserRegistration file. So lets assume some day you need to change the directory structure your application will break as the relative path you had provided now it does'nt exist.
But in Method 2 you always use the namespace you provided \ The filename instead of where you want to use. So even you change the directory structure you don't have to got all codes and modify the path. It will work as it was.
To know more study about how to use namespace and composer.
I was wondering if it's possible to use a static PHP class (or a method of that class, should I say) without calling it via the namespace ala laravel?
I realise this is conflicting with the nature of namespaces, but I was mainly wanting to use them the same as Laravel does, where I can just call Example::method('test') rather than \example\example\Example::method('test')
At the top of your file, declare a use statement which creates an alias:
use example\example\Example;
Example::method('test'); //resolves to example\example\Example::('test')
You can even use a different name with 'as':
use example\example\Example as MyAlias;
MyAlias::method('test'); //resolves to example\example\Example::('test')
See http://php.net/manual/en/language.namespaces.importing.php for more information.
Note: This is not how laravel facades work but I think it is what you are looking for. If you want something more automatic then aliasing you will have to incorporate some logic into your autoloader.
So, I have a few classes I'm trying to use PHP's namespaces with and am having some trouble accessing the functions in the lowest level class.
Here's how it's laid out...
Activity -> Post
Activity has a namespace of activity and Post has a namespace of post
At the top of my Post class I have this code.
namespace Post;
use activity\activity;
That's the code that PHPStorm created when I made my class file and then extended my Activity class.
So, when I try to access my public functions inside Post, I have tried both of these methods...
\activity\post::function();
AND
$post = new \activity\post();
$post->function();
But PHPStorm tells me neither of those exist.
So, what's the actual way to access these lower level functions?
I've googled quite a bit but apparently I'm not searching for the right thing because I haven't found anything about sub classes.
Thanks so much for your help in understanding how this works.
Don't use \activity, use activity.
\activity is using the \ (or base) namespace.
Use doesn't extend a class, it creates an alias. Since you have Use activity\activity this makes it so you can access functions in the activity class by running activity::function() rather than using the full namespace \activity\activity::function().
You can also define use \activity\activity as test and access functions like test::function().
I'm not sure of the point of having the namespaces the same name as the classes though but sjagr addressed that in comments.
I'm developing some packages a lot of which are based on code that was in the main app, or from examples that are based on writing the code in an app rather than a package. I keep forgetting to add a Use View; or Use Controller; in the various files and am having to manually check and add these to every single PHP script (that needs them) in the package.
Is there a way of automating this so that I only have to declare them once in a package, or better still get them to pass through to the facades in the main app?
I'm afraid there isn't.
This is because your package code has its own namespace, and so does the Illuminate core.
PHP's use-statements are only on per-file basis.
When your scripts uses classes from another namespace, you have 2 options.
Adding use-statements (to the Facades) to alias the class to the current namespace
Referencing the full namespace of the facade (starting from the global namespace ), either the alias in the global namespace which Laravel automatically creates (\View), or the original full namespace of the facade (\Illuminate\Support\Facades\View)
Example of referencing the full namespace:
<?php
namespace My\Package;
class SomeClass
{
public function doSomething()
{
// reference full namespace
$view = \Illuminate\Support\Facades\View::make('someview');
// or
$view = \View::make
}
}
?>
This might seem as a way to not have to use use-statements, but in my opinion it's worse. So I recommend u to just get used to adding these use-statements.
You should see it as a best practice: these use-statements clearly state the dependencies of your class (or file). It's always better to try and lower the amount of these.