PHP Velho Oeste 2024

class sözcüğü

Bir sınıf, değişkenlerden ve bu değişkenlerle çalışan işlevlerden oluşan bir bütündür. Değişkenler var anahtar sözcüğüyle belirtilir, işlevler ise function ile tanımlanır. Bir sınıf şöyle bir söz dizimi ile tanımlanır:

<?php
class Sepet {
    var 
$mallar;  // Sepetteki mallar

    // $malnum numaralı $adet adet malı sepete ekle

    
function mal_ekle($malnum$adet) {
        
$this->mallar[$malnum] += $adet;
    }

    
// $malnum numaralı $adet adet malı sepetten sil

    
function mal_sil($malnum$adet) {
        if (
$this->mallar[$malnum] > $adet) {
            
$this->mallar[$malnum] -= $adet;
            return 
true;
        } elseif (
$this->mallar[$malnum] == $adet) {
            unset(
$this->mallar[$malnum]);
            return 
true;
        } else {
            return 
false;
        }
    }
}
?>

Bu örnekte, sepetteki malları içeren bir ilişkisel dizi ile sepete malları ekleyip çıkarmak için iki işlevden oluşan Sepet sınıfı tanımlanmaktadır.

Uyarı

Bir sınıf tanımını birden fazla dosyaya yayamayacağınız gibi yöntem bildirimi dışında birden fazla PHP bloğuna da bölemezsiniz. Aşağıdaki örnek çalışmayacaktır:

<?php
class Deneme {
?>
<?php
    
function dene() {
        print 
'TAMAM';
    }
}
?>

Ancak, buna izin verilir:

<?php
class Deneme {
    function 
dene() {
        
?>
        <?php
        
print 'TAMAM';
    }
}
?>

Aşağıdaki Dikkat bölümleri PHP 4 içindir.

Dikkat

stdClass ismi Zend tarafından yerleşik sınıf ismi olarak ayrılmıştır. stdClass ismini kendi sınıflarınızda kullanamazsınız.

Dikkat

__sleep ve __wakeup işlev isimleri PHP sınıfları için sihirlidir. Bunlarla ilgili sihirli işlevselliğe ihtiyacınız olmadığı sürece bu işlev isimlerini sınıflarınızın içinde kullanamazsınız. Daha ayrıntılı bilgi için belgenin devamına bakınız.

Dikkat

PHP, __ ile başlayan tüm işlev isimlerini kendi yerleşik işlev isimleri için ayırmıştır. PHP'de özellikle belgelenmiş sihirli işlevselliğe ihtiyacınız olmadığı sürece böyle işlev isimleri kullanmanız önerilmez.

PHP 4'te var değişkenlerinin sadece sabitlerle ilklendirilmesine izin verilir. Değişkenleri sabit olmayan değerlerle ilklendirmek isterseniz, sınıf bir nesne olarak örneklendiği anda kendiliğinden çağrılan bir ilklendirici işlev üzerinden bunu yapabilirsiniz. Bu ilklendirici işleve kurucu işlev denir (aşağıya bakınız).

<?php
class Sepet {
    
/* Bunların hiçbiri PHP 4'te çalışmaz. */
    
var $bugun date("Y-m-d");
    var 
$ad $ilkad;
    var 
$sahibi 'Fred ' 'Jones';
    
/* Sabit değer içeren diziler çalışır. */
    
var $mallar = array("VCR""TV");
}

/* Bu iş böyle yapılır. */
class Sepet {
    var 
$bugun;
    var 
$ad;
    var 
$sahibi;
    var 
$mallar = array("VCR""TV");

    function 
Sepet() {
        
$this->bugun date("Y-m-d");
        
$this->ad $GLOBALS['ilkad'];
        
/* ve saire. . . */
    
}
}
?>

Sınıflar veri türleridir, yani asıl değişkenlerin örüntüsüdürler. Bu tür bir değişkeni new işleci ile oluşturabilirsiniz.

<?php
$sepet 
= new Sepet;
$sepet->mal_ekle("10"1);

$diger_sepet = new Sepet;
$diger_sepet->mal_ekle("0815"3);
?>

Bu örnekte, Sepet sınıfından $sepet ve $diger_sepet diye iki nesne oluşturulmakta ve $sepet nesnesinin mal_ekle işlevi ile $sepet'e "10" numaralı malzemeden 1 adet, $diger_sepet'e de "0815" numaralı malzemeden 3 adet eklenmektedir.

$sepet ve $diger_sepet nesnelerinin ikisi de mal_ekle ve mal_sil işlevleri ile mallar değişkenine sahiptir. Bunlar isimleri aynı olsa da birbirlerinden bağımsız işlev ve değişkenlerdir. Nesneleri, bir dosya sisteminin dizinleri olarak düşünebilirsiniz. Bir dosya sisteminde ayrı ayrı dizinlerde BENi.OKU adında iki farklı dosyanız olabilir. Bu dosyalara kök dizinden ayrı ayrı erişmek isterseniz dosyaların tam yollarını yazmanız gerekir. Tıpkı bunun gibi PHP'de de bir nesne işlevini çağırmak için istediğiniz işlevin tam yolunu yazmanız gerekir. İşlemi PHP'ye tercüme edersek: Kök dizin, küresel alana; dosya yolu ayracı, -> ayracına karşılıktır. Dolayısıyla, $sepet->mallar ile $diger_sepet->mallar iki ayrı değişkendir. Burada şuna dikkat edin: Değişkenin ismi $sepet->mallar'dır, $sepet->$mallar değildir. PHP $sepet->$mallar dizgesini $ imli iki değişken ismi olarak ele alır.

<?php
// tek $ imiyle, doğru
$sepet->mallar = array("10" => 1);

// $sepet->$mallar, $sepet->"" haline gelir, geçersiz
$sepet->$mallar = array("10" => 1);

// $sepet->$ogeler, $sepet->mallar haline gelir,
// istenen bu olmasa da yorum olarak doğrudur
$ogeler 'mallar';
$cart->$ogeler = array("10" => 1);
?>

Bir sınıf tanımı içinde, betiğinizin neresinden hangi nesne ismiyle bu sınıfın örnekleneceğini bilemezsiniz. Yani, Sepet sınıfının yazıldığı sırada bu sınıfın $sepet veya $diger_sepet ya da başka bir isimle örnekleneceği kararını henüz vermemişsinizdir. Bu bakımdan, Sepet sınıfının içinde $sepet->mallar diye bir değişken ismi kullanamazsınız. Sınıfın kendi işlev ve değişkenlerine erişirken bu amaçla 'benim', 'geçerli nesnem' anlamında $this sözde değişkeni kullanılır. Bu bakımdan '$this->mallar[$malnum] += $adet;' deyimi, "(benim) mallar dizimin $malnum elemanına $adet değerini ekle" veya "geçerli nesnenin mallar dizisinin $malnum elemanına $adet değerini ekle" olarak okunabilir.

Bilginize:

$this sözde değişkeni sınıfın kendi yöntemi duruk olarak çağrıldığı takdirde tanımlı değildir. Ancak bu, "$this, bir yöntem başka bir nesnenin içinden duruk olarak çağrıldığında tanımlıdır." tarzında anlaşılmamalıdır. Böyle bir durumda $this'in değeri çağrıldığı nesne olacaktır. Bunu bir örnekle pekiştirelim:

<?php
class A
{
    function 
foo()
    {
        if (isset(
$this)) {
            echo 
'$this tanımlı (';
            echo 
get_class($this);
            echo 
")\n";
        } else {
            echo 
"\$this tanımsız.\n";
        }
    }
}

class 
B
{
    function 
bar()
    {
        
A::foo();
    }
}

$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>

Yukarıdaki örneğin çıktısı:

$this tanımlı (A)
$this tanımsız.
$this tanımlı (B)
$this tanımsız.

Bilginize:

Sınıflar ve nesnelerle çalışırken kullanışlı olabilen bazı işlevler vardır. Bunları Sınıf/Nesne İşlevleri bölümünde bulabilirsiniz.

add a note add a note

User Contributed Notes 5 notes

up
7
ender911t at gmail dot com
8 years ago
Overrides in child are called when calling a function from the parent

<?PHP
class Par
{
   var
$test;
   function
__construct($in)
   {
     
$this->test = $in;
   }

   function
getTest()
   {
      return
$this->test;
   }

   function
runTest()
   {
      return
$this->getTest();
   }
}

class
Chi extends Par
{
   var
$i;
   function
__construct($in)
   {
     
$this->i = $in;
     
parent::__construct($in."X");
   }

   function
getTest()
   {
      return
$this->i;
   }

   function
runParentTestA()
   {
      return
parent::runTest();
   }

   function
runParentTestB()
   {
      return
parent::getTest();
   }
}

$p = new Par("par");
$c = new Chi("chi");

echo
$p->runTest()." == par";
echo
$c->runTest()." == chi";
echo
$c->runParentTestA()." == chi";
echo
$c->runParentTestB()." == chiX";
?>
up
5
anthonymccuen at yahoo dot com
11 years ago
You can also use "var" to declare multiple public instance variables like in C:

int main(int *argc, const char *argv[]) {
    int a, b, c, d, e, f;
   
    a = 50;
    // blah blah blah code here
    // ...
   
    return 0;
}

Same as PHP:

<?php
class MyClass {
    var
$myvar, $anotherVar, $something, $str;
}
?>
up
1
masonswolf at gmail dot com
11 years ago
You can invoke a class above its definitions in some cases, but there are very important exceptions to this behavior. If your class extends another class, and the interpreter doesn't see the extended class first, then it won't be added to the symbol table until the code has stepped through it in runtime. As a result, if you try to invoke it above the definition, you'll get a "class not found" fatal error.

And those suck.

So, to provide an example, the following will output a fatal error
<?php
Bar
::bar();
exit;

class
Bar extends Foo { } //will fatal because Foo not seen yet

class Foo {
    static function
bar() { echo 'yep, this is Foo::bar'; }
}
?>

However, THIS code will work just fine:
<?php
Bar
::bar();
exit;

class
Foo {
    static function
bar() { echo 'yep, this is Foo::bar'; }
}

class
Bar extends Foo { } //will work because Foo came first
?>

Notice that if you include a file containing the class you will extend, and then extend the class in the same file as its invocation, you can also get the class not found fatal. This happens even if the 'include' call happens before the child class's definition.

Eg. the following will also output a fatal error
<?php
include_once('file_with_foo.php');

Bar::bar();
exit;

class
Bar extends Foo { }
?>

Hope that clarifies things.
up
-9
pov at fingerprint.fr
12 years ago
I just discovered a behaviour that has to be mentioned.

Let's consider the following file

<?php
Foo
::bar();
exit;

class
Foo {
  function
bar() { echo 'yep, this is Foo::bar'; }
}
?>

You may expect :
- an error on the Foo::bar call, because the class is not defined
- removing the code after the exit without side-effect

But it won't, and it will output the string !
It seems every class definition is executed at parse-time.

But without errors; if your file is
<?php
Foo
::bar();
exit;

class
Foo {
  function
bar() { echo 'yep, this is Foo::bar'; }
}
class
Foo {
  function
bar() { echo 'yep, this is another Foo::bar'; }
}
?>
it will still output the first string, not doing any "Already exiting class" error !

So if you intend preventing a double include by doing in an included file :
<?php
if (class_exists('Foo')) { return; }

class
Foo {
  static function
register() { ... }
}
Foo::register();
?>
the Foo::register method won't be called !

Very strange development choice; I suppose it is due to ascending compatibility.
Hope it can help...
up
-10
boukeversteegh at gmail dot com
13 years ago
You can also instantiate objects using variables containing the name of the class:

<?php

$type
= 'Foo';
$foo   = new $type();

print_r( $foo );
/* Prints:
Foo Object
(
)
*/
?>

The following works as well:
<?php

$somefoo   
= new Foo();
$anotherfoo = new $somefoo();

# so you don't have to do:
$anotherfoo = new get_class( $somefoo)();
?>
To Top