İsim alanları ve devingen dil özellikleri

PHP'nin isim alanları gerçeklenimi bir programlama dili olarak PHP'nin kendi devingen doğasından etkilenir. Örnek olarak aşağıdaki kodu isim alanlı koda dönüştürmek istersek:

Örnek 1 - Devingen olarak erişilen elemanlar

örnek1.php:

<?php
class sınıfadı
{
    function 
__construct()
    {
        echo 
__METHOD__,"\n";
    }
}
function 
işlevadı()
{
    echo 
__FUNCTION__,"\n";
}
const 
sabitadı "küresel";

$a 'sınıfadı';
$obj = new $a;                   // sınıfadı::__construct basar
$b 'işlevadı';
$b();                            // işlevadı basar
echo constant('sabitadı'), "\n"// küresel basar
?>
Tamamen nitelenmiş isim kullanmak gerekir (isim alanı önekli sınıf adı). Bir devingen sınıf, işlev veya sabit ismi içinde bir nitelenmiş isim ile tamamen nitelenmiş isim arasında bir fark olmadığından baştaki ters bölünün gereksiz oluşuna dikkat edin.

Örnek 2 - Devingen olarak erişilen isim alanlı elemanlar

<?php
namespace isimalanıadı;
class 
sınıfadı
{
    function 
__construct()
    {
        echo 
__METHOD__,"\n";
    }
}
function 
işlevadı()
{
    echo 
__FUNCTION__,"\n";
}
const 
sabitadı "isimalanlı";

include 
'örnek1.php';

$a 'sınıfadı';
$obj = new $a;                    // sınıfadı::__construct basar
$b 'işlevadı';
$b(); // prints funcname
echo constant('sabitadı'), "\n"// küresel basar

/* çift tırnakları kullanacaksanız, "\\isimalanıadı\\sınıfadı"
   biçiminde olmalıdır */
$a '\isimalanıadı\sınıfadı';
$obj = new $a// isimalanıadı\sınıfadı::__construct basar
$a 'isimalanıadı\sınıfadı';
$obj = new $a// bu da isimalanıadı\sınıfadı::__construct basar
$b 'isimalanıadı\işlevadı';
$b(); // isimalanıadı\işlevadı basar
$b '\isimalanıadı\işlevadı';
$b(); //bu da isimalanıadı\işlevadı basan
echo constant('\isimalanıadı\sabitadı'), "\n"// isimalanlı basar
echo constant('isimalanıadı\sabitadı'), "\n"// bu da isimalanlı basar
?>

SSS arasındaki Dizgelerdeki isim alanı adlarının öncelenmesi konusuna da bakmayı unutmayın.

add a note add a note

User Contributed Notes 5 notes

up
49
Alexander Kirk
6 years ago
When extending a class from another namespace that should instantiate a class from within the current namespace, you need to pass on the namespace.

<?php // File1.php
namespace foo;
class
A {
    public function
factory() {
        return new
C;
    }
}
class
C {
    public function
tell() {
        echo
"foo";
    }
}
?>

<?php // File2.php
namespace bar;
class
B extends \foo\A {}
class
C {
    public function
tell() {
        echo
"bar";
    }
}
?>

<?php
include "File1.php";
include
"File2.php";
$b = new bar\B;
$c = $b->factory();
$c->tell(); // "foo" but you want "bar"
?>

You need to do it like this:

When extending a class from another namespace that should instantiate a class from within the current namespace, you need to pass on the namespace.

<?php // File1.php
namespace foo;
class
A {
    protected
$namespace = __NAMESPACE__;
    public function
factory() {
       
$c = $this->namespace . '\C';
        return new
$c;
    }
}
class
C {
    public function
tell() {
        echo
"foo";
    }
}
?>

<?php // File2.php
namespace bar;
class
B extends \foo\A {
    protected
$namespace = __NAMESPACE__;
}
class
C {
    public function
tell() {
        echo
"bar";
    }
}
?>

<?php
include "File1.php";
include
"File2.php";
$b = new bar\B;
$c = $b->factory();
$c->tell(); // "bar"
?>

(it seems that the namespace-backslashes are stripped from the source code in the preview, maybe it works in the main view. If not: fooA was written as \foo\A and barB as bar\B)
up
13
guilhermeblanco at php dot net
8 years ago
Please be aware of FQCN (Full Qualified Class Name) point.
Many people will have troubles with this:

<?php

// File1.php
namespace foo;

class
Bar { ... }

function
factory($class) {
    return new
$class;
}

// File2.php
$bar = \foo\factory('Bar'); // Will try to instantiate \Bar, not \foo\Bar

?>

To fix that, and also incorporate a 2 step namespace resolution, you can check for \ as first char of $class, and if not present, build manually the FQCN:

<?php

// File1.php
namespace foo;

function
factory($class) {
    if (
$class[0] != '\\') {
        echo
'->';
        
$class = '\\' . __NAMESPACE__ . '\\' . $class;
    }

    return new
$class();
}

// File2.php
$bar = \foo\factory('Bar'); // Will correctly instantiate \foo\Bar

$bar2 = \foo\factory('\anotherfoo\Bar'); // Wil correctly instantiate \anotherfoo\Bar

?>
up
4
akhoondi+php at gmail dot com
4 years ago
It might make it more clear if said this way:

One must note that when using a dynamic class name, function name or constant name, the "current namespace", as in http://www.php.net/manual/en/language.namespaces.basics.php is global namespace.

One situation that dynamic class names are used is in 'factory' pattern. Thus, add the desired namespace of your target class before the variable name.

namespaced.php
<?php
// namespaced.php
namespace Mypackage;
class
Foo {
    public function
factory($name, $global = FALSE)
    {
        if (
$global)
           
$class = $name;
        else
           
$class = 'Mypackage\\' . $name;
        return new
$class;
    }
}

class
A {
    function
__construct()
    {
        echo
__METHOD__ . "<br />\n";
    }
}
class
B {
    function
__construct()
    {
        echo
__METHOD__ . "<br />\n";
    }
}
?>

global.php
<?php
// global.php
class A {
    function
__construct()
    {
        echo 
__METHOD__;
    }
}
?>

index.php
<?php
//  index.php
namespace Mypackage;
include(
'namespaced.php');
include(
'global.php');
 
 
$foo = new Foo();
 
 
$a = $foo->factory('A');        // Mypackage\A::__construct
 
$b = $foo->factory('B');        // Mypackage\B::__construct
 
 
$a2 = $foo->factory('A',TRUE);    // A::__construct
 
$b2 = $foo->factory('B',TRUE);    // Will produce : Fatal error: Class 'B' not found in ...namespaced.php on line ...
?>
up
0
m dot mannes at gmail dot com
9 months ago
Case you are trying call a static method that's the way to go:

<?php
class myClass
{
    public static function
myMethod()
    {
      return
"You did it!\n";
    }
}

$foo = "myClass";
$bar = "myMethod";

echo
$foo::$bar(); // prints "You did it!";
?>
up
0
scott at intothewild dot ca
8 years ago
as noted by guilhermeblanco at php dot net,

<?php

 
// fact.php

 
namespace foo;

  class
fact {

    public function
create($class) {
      return new
$class();
    }
  }

?>

<?php

 
// bar.php

 
namespace foo;

  class
bar {
  ...
  }

?>

<?php

 
// index.php

 
namespace foo;

  include(
'fact.php');
 
 
$foofact = new fact();
 
$bar = $foofact->create('bar'); // attempts to create \bar
                                  // even though foofact and
                                  // bar reside in \foo

?>
To Top