In my php file i am doing it this way
pagecontroller.php
include_once(RUDRA."/controller/AbstractTemplateController.php");
if (file_exists(get_include_path() . CONTROLLER_PATH . "/TemplateController.php" )) {
include_once (CONTROLLER_PATH . "/TemplateController.php");
} else {
include_once (RUDRA . "/controller/TemplateController.php");
}
in TemplateController.php a class named 'TemplateController extends AbstractTemplateController' is defined, if a developer has already defined a class TemplateController which also extends AbstractTemplateController then it will use that otherwise it will fallback to default definition.
then in other files i will simply use something like this
include_once("pagecontroller.php")
$c = new TemplateController();
is there any better way to do this?
since I am including two files AbstractTemplateController.php & TemplateController.php in both cases, I cpuld have written both class definitions in same file which would have saved one include(if there is no custom TemplateController.php)?
I tried writing AbstractTemplateController & TemplateController in one single file but if then developer has defined his own TemplateController it creates two classes with same name situation.
pupose is to have atleast one definition to be there, if customDefinition does not exists then only use default one. and this code is to be abstract.
in the beginning if CustomClass exists (in a specific folder) then that the definition to be used, else use default one (which is nothing but simply extends AbstractOne)
CONTROLLER_PATH . "/TemplateController.php"
class TemplateController extends AbstractTemplateController {
/* over-ridden method of AbstractTemplateController
*/
public function invoke($abc,$def){
echo $abc . " " .$def;
}
}
RUDRA . "/controller/TemplateController.php"
class TemplateController extends AbstractTemplateController {
// nothing at all this is simply to make sure TemplateController class is available
// for others to use.
}
Use namespaces and convention.
E.g. you could check if there's a TemplateController-class present that extends the AbstractTemplateController that's different from your namespace (As your implementation will be specific for your namespace), if there isn't ; fall back to your implementation of the TemplateController.
http://php.net/manual/en/language.namespaces.php
php provides a function for not letting you load/write a class more then once.
bool class_exists ( string $class_name );
example is :
<?php
function __autoload($class)
{
include($crigger_error("Unable to load class: $class", E_USER_WARNING);
}
}
if (class_exists('MyClass')) {
$myclass = new MyClass();
}lass . '.php');
// Check to see whether the include declared the class
if (!class_exists($class, false)) {
trigger_error("Unable to load class: $class", E_USER_WARNING);
}
}
if (class_exists('MyClass')) {
$myclass = new MyClass();
}
?>
in above example autoload is used, you could do it without autoload this way :
<?php
// Check that the class exists before trying to use it
if (class_exists('MyClass')) {
$myclass = new MyClass();
}
?>
still i am saying you better get habit of using namespaces. they are awesome and work every where.
Is it possible to use a classes methods without actually calling the class into a variable. I am sure i have seen this somewhere but i'm not sure if i was dreaming.
Take this example:
<?php
namespace proj;
class beer{
public function whichIsBest(){
return 'Not cheap stuff';
}
}
Include the file start the class but then how can i get to the whishIsBest method without calling the class into a variable first.
<?php
include 'beerClass.php';
new \proj\beer();
echo \proj\beer()->whichIsBest
Or is this just not possible and I was actually dreaming?
http://www.php.net/manual/en/language.oop5.static.php
class beer {
public static function whichIsBest() {
do //
}
}
..
echo beer::whichIsBest();
This is an experiment with PHP namespaces / autoload in a single file.
namespace trust;
class trust_network{
public function __construct(){
print "SUP";
}
}
namespace trust2;
$trust = new \trust\trust_network(); $do = new \test();
function __autoload($class){
require($class.".php");
print $class;
}
So under namespace trust2, I'm calling "\test" - aka I'd like to autoload that class from an external file on a global base. What I wrote does not work. I know that I've got __autoload under a namespace, but how do I declare that on a global basis? Can't include before namespace declaration.
For multiple namespaces in one file you should use the curly bracket syntax:
namespace n1 {
...
}
namespace n2 {
...
}
namespace {
...
}
In the last block you can declare functions in the global namespace. Reference: http://www.php.net/manual/en/language.namespaces.definitionmultiple.php
Autoload is usually so that you can put one class per file. Therefore, you should have the following layout
/index.php
function __autoload($class){
// You may need to convert backslashes in $class to forward slashes
// and strip the first slash, we'll leave the
require($class.".php");
// debug-only: print $class;
}
// Calling new here triggers __autoload to be called
$trust = new \trust\trust_network();
$do = new \test();
/trust/trust_network.php
namespace trust;
class trust_network{
public function __construct(){
print "TRUST_NETWORK";
}
}
/test.php
class test() {
public function __construct(){
print "TEST";
}
}
Note that you should use spl_autoload_register instead since it allows multiple systems to hook in their own autoload behavior. As of PHP 5.3, you can do the following
spl_autoload_register(function ($class) {
require($class.".php");
});
I posted some questions previously regarding the use of Namespaces in PHP and from what I got, this example code I have below should be working.
However I am getting errors when I try to use Namespace in PHP like this. Here is the first error when running the code below as is...
Fatal error: Class 'Controller' not found in E:\Controllers\testing.php on line 6
E:\Controller\testing.php File
<?php
use \Controller;
include('testcontroller.php');
$controller = new Controller;
$controller->show();
?>
E:\Controller\testcontroller.php File
<?php
use \Library\Registry;
namespace Controller
{
class Controller
{
public $registry;
function __construct()
{
include('E:\Library\Registry.class.php');
$this->registry = new Registry;
}
function show()
{
echo $this->registry;
echo '<br>Registry was ran inside testcontroller.php<br>';
}
}
}
?>
E:\Library\Registry.class.php File
<?php
namespace Library\Registry
{
class Registry
{
function __construct()
{
return 'Registry.class.php Constructor was ran';
}
}
}
?>
As you can see I tried to make it as simple as possible just to get the Namespace part working. I have tried different variations and cannot seem to figure it out.
Even when using use statement, you need to specify the namespace of the class you are trying to instantiate. There are a lot of examples here: http://www.php.net/manual/en/language.namespaces.importing.php
To understand it better, I will describe to you how it works. In your case, when you do use \Controller, the whole Controller namespace becomes available to you, but not the classes that are in this namespace. So, for example:
<?php
include('testcontroller.php');
use \Controller;
// Desired class is in namespace!
$controller = new Controller\Controller();
// Error, because in current scope there is no such class
$controller = new Controller();
$controller->show();
?>
Another example:
testcontoller.php:
<?php
namespace Some\Path\To\Controller;
class Controller
{
function __construct()
{
}
function show()
{
echo '<br>Was run inside testcontroller.php<br>';
}
}
?>
testing.php:
<?php
include('testcontroller.php');
use \Some\Path\To\Controller;
// We now can access Controller using only Controller namespace,
// not Some\Path\To\Controller
$controller = new Controller\Controller();
// Error, because, again, in current scope there is no such class
$controller = new Controller();
$controller->show();
?>
If you wish to import exactly the Controller class, you need to do use Controller\Controller - then this class will be accessible in your current scope.
Its not that good idea to name the namespace, like the class, because it is confusing (and I think this is what happens here). There moment you define the alias via use Controller this referenes to either a class \Controller, or the namespace \Controller, but your class, because it is within the namespace, is named \Controller\Controller 1
use Controller;
$class = new Controller\Controller;
or
$class = new \Controller\Controller;
or
use Controller\Controller;
$class = new Controller;
The idea is, that the moment you try to access a class with its relative name it tries to map the "first part" against any alias defined using use (remeber use MyClass is the same as use MyClass as MyClass. The thing after as is the alias).
namespace MyNamespace\MyPackage\SomeComponent\And\So\On {
class MyClass {}
}
namespace Another {
use MyNamespace\MyPackage\SomeComponent; // as SomeComponent
$class = new SomeComponent\An\So\On\MyClass;
}
As you can see PHP finds SomeComponent as the first part and maps it against the SomeComponent-alias the line above.
You can read more about it in the manual about namespaces.
1 Its called "Full-qualified classname", if you name a class with its complete name.
When you put a class Controller in the namespace Controller, then you have to reference it that way:
$controller = new Controller\Controller();
\Controller would be a class in the global (default) namespace, i.e. as if you used no namespace at all.
Strangely I have found that in my example code from the Question above, if I change all the Namespace's that are defined to something like MyLibrary so it would be like this code below...
E:\Library\Registry.class.php File
<?php
namespace MyLibrary
{
class Registry
{
function __construct()
{
echo 'Registry.class.php Constructor was ran';
}
}
}
?>
Then when I use use MyLibrary\Registry; in another file, I am able to access it how I had planned...
$this->registry = new Registry;
The reason this is very strange to me is this now makes a class name appear to be a Namespace as well. So I would not need to set a Namespace to 'MyLibrary\Library' to access the Registry instead I would do it like I showed in this answer to be able to access it with just calling the name of the class.
I hope this makes sense and helps someone else. I will not accept this as the answer as I am hoping someone with more know-how will come in and post a better Answer with explanation
try
<?php
use \Library\Registry;
namespace Controller;
class Controller
{
public $registry;
function __construct()
{
include('E:\Library\Registry.class.php');
$this->registry = new Registry;
}
function show()
{
echo $this->registry;
echo '<br>Registry was ran inside testcontroller.php<br>';
}
}
?>
and
<?php
namespace Library\Registry;
class Registry
{
function __construct()
{
return 'Registry.class.php Constructor was ran';
}
}
?>
First off, I believe you are using composer or composer is initialised in your project. If so, check composer.json file for your autoload, psr-4 definition. For example, if the root of your application is "App", then in your psr-4, you should be doing "autoload": { "psr-4": { "App\\": "./" } },
Furthermore, remember to clear composer cache and dump-autoload from the terminal as follows:
composer clear-cache
composer dump-autoload
I work a lot in PHP but I never really understand the namespace method in PHP. Can somebody help me here? I have read on php.net's website its not explained good enough, and I can't find examples on it.
I need to know how I can make code in sample version.
namespace: sample
class: sample_class_1
function: test_func_1
class: sample_class_2
function: test_func_2
function: test_func_3
Like this?
<?php
namespace sample
{
class Sample_class_1
{
public function test_func_1($text)
{
echo $text;
}
}
class Sample_class_2
{
public static function test_func_2()
{
$c = new Sample_class_1();
$c->test_func_1("func 2<br />");
}
public static function test_func_3()
{
$c = new Sample_class_1();
$c->test_func_1("func 3<br />");
}
}
}
// Now entering the root namespace...
// (You only need to do this if you've already used a different
// namespace in the same file)
namespace
{
// Directly addressing a class
$c = new sample\Sample_class_1();
$c->test_func_1("Hello world<br />");
// Directly addressing a class's static methods
sample\Sample_class_2::test_func_2();
// Importing a class into the current namespace
use sample\Sample_class_2;
sample\Sample_class_2::test_func_3();
}
// Now entering yet another namespace
namespace sample2
{
// Directly addressing a class
$c = new sample\Sample_class_1();
$c->test_func_1("Hello world<br />");
// Directly addressing a class's static methods
sample\Sample_class_2::test_func_2();
// Importing a class into the current namespace
use sample\Sample_class_2;
sample\Sample_class_2::test_func_3();
}
If you're in another file you don't need to call namespace { to enter the root namespace. So imagine the code below is another file "ns2.php" while the original code was in "ns1.php":
// Include the other file
include("ns1.php");
// No "namespace" directive was used, so we're in the root namespace.
// Directly addressing a class
$c = new sample\Sample_class_1();
$c->test_func_1("Hello world<br />");
// Directly addressing a class's static methods
sample\Sample_class_2::test_func_2();
// Importing a class into the current namespace
use sample\Sample_class_2;
sample\Sample_class_2::test_func_3();