Calling static autoloaded class without namespace - php

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.

Related

How and where should I use the keyword "use" in php

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.

How do I access a subclass's functions using namespaces?

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.

PHP PSR-0 Static Class

I'm trying to rewrite an OO PHP site (that loosely follows an MVC structure) so it uses namespaces - and want to follow PSR-0.
In the current site I have a class (called APP) which is full of static methods that I call all over the place to handle things such as getting config data eg; APP::get_config('key').
Obviously with namespacing, I would need to call \TheNameSpace\App::get_config('key'). I use this class frequently, so want to avoid having to prefix the namespace every time I use it. I do call methods in it from within other classes, which would usually be under a sub-namespace - so changing the namespace at the top of the file won't really work.
So, I guess my question is, what is the easiest way to have a 'global' class with methods that I can call anywhere without having to prefix with the namespace each time?
namespace Foo;
use Bar;
Then you do not have to do \Bar\fn
So in your case:
namspace Foo;
use TheNameSpace\App;
App::get_config('blah')
Read the section in the php manual on using/aliasing namespaces.
http://www.php.net/manual/en/language.namespaces.importing.php
You can exclude the namespace by using "use". You can name it whatever you want.
use TheNamespace\App as App //You can name it anything here
App:config('key');
At top of your scripts add
use TheNameSpace\App as MyApp
for example. You can then use it like
app = new MyApp();
in your scripts. Of course you needn't to use an alias here. Just
use TheNameSpace\App
app = new App();
will work, too.
A global class that's implementing this one is bad style and you shouldn't do it like this:
class MyApp extends TheNameSpace\App { }
....
myApp = new MyApp();

Load a class with a different name than the one passed to the autoloader as argument

basically, I have the following problem: I want to make use of PHP's new namespace features. Unfortunately, I'm running a PHP version (5.3.2) in which namespace-autoload-support for linux still seems buggy and does not work (PHP should be able to load the class file automatically by its namespace without having to use a custom autoloader, but that doesn't work).
What I want to achieve is to write an autoloader that I can simply remove as soon as the php's namespace features work correctly (there seems to be a speed advantage when not using a custom autoloader) with having to change as less code as possible afterwards.
So I have a call like this:
$filereader = new system\libraries\file\XML();
which gets passed correctly as the string "system\libraries\file\XML" to my autoload-function. I can load the corresponding file "system/libraries/file/XML.class.php". However, the class in there will be named
class XML { ... }
(or something different than "system\libraries\file\XML") and so have a different name than the one by which PHP will try to load it. So is there an easy way to load that class ("XML") which has a different name than the name which I pass to the autoloader function? Can I perhaps do something in the autoloader to achieve that behaviour? (I'm using spl_autoload_register).
I know that even if it worked out I would still not be able to use all features of namespacing, since a (simple) autoloader would not respect the "use namespace" directive and I would still have to use rather long names for loading a class. However, if I understood PHP's namespace-features correctly, I could leave the code as it is when I later switch to using native namespace support instead of my autoloader.
If what I try to do does not make sense at all in your opinion or if I misunderstood namespaces, please tell me (- I have not used PHP's namespace features yet).
I would load the file (which creates the XML class) and then alias the XML class to the properly namespaced system\libraries\file\XML class:
class_alias('XML', 'system\libraries\file\XML');
More generally:
class_alias(basename($class), $class));
Though I'm not quite sure whether class_alias can alias to namespaced classes...

Why does Codeigniter assume I want to create an instance of the class when using $this->load?

In Codeigniter, when we use $this->load('class_name') in the controller, CI will try to create an instance of the class/model using its constructor.
But sometimes, I don't actually need an instance from that class, I just want to call some static functions from it. Also, there is a big limitation with $this->load('class_name'), it does not allow me to pass parameters to the constructor (unless we extend or modify the core class of CI).
I think the $this->load('class_name') function should only do a require_once on the class php file for me, and let me freely do things (create instance/call static functions) with the class in the controller.
Should I simply ignore this function and use require_once or writing my own __autoload function to load up the classes? This way, I just feel strange because it seems I am not writing codes inside the CI box.
You can pass parameters to your constructor. See the "Passing Parameters When Initializing Your Class" section in the user guide.
I found CodeIgniter's object creation and loading to be very limiting. I want full control over my code, and little magic in the background. I have instead started using Doctrine's Class Loader. It's very lightweight and is essentially SPL autoloading (also a good alternative). You don't need the whole Doctrine shebang with ORM and all that stuff, just the ClassLoader. There's some configuration tinkering to get this right, but it works wonders.
With PHP 5.3 I now have namespaced classes in the Application directory. For instance I created a new class in the Tests directory: Application\Tests\SomeTest.php
That test could look something like this:
namespace Tests;
class SomeTest {
...
}
I would use this class in my code (controllers, views, helpers) by simply using the fully qualified namespace (i.e. $test = new \Tests\SomeTest) or a "use" statement at the top of my code (use \Tests\SomeTest as SomeTest).
In this way I intend to replace all libraries and models with OO namespaced variants. There are many benefits to this: fast autoloading with SPL, full IDE intellisense support for classes/methods (CodeIgniter is really bad for that), your code is more portable to other frameworks or projects.
That said, I still use a lot of the CodeIgniter engine. This basically means I have $CI =& get_instance() in most of my classes. It's still a work in progress and I think the main reason I need CI is for it's database access. If I can factor that out ... and use something like Dependency Injection, then I won't need CodeIgniter in my classes at all. I will simply be using it for it's MVC framework, and using it's methods occasionally in my controllers.
I know this goes above and beyond your question, but hopefully it's some food for though - and it helps me to get it in writing too.

Categories