CakeFest 2024: The Official CakePHP Conference

Özellikler

Sınıf üyesi değişkenlere özellik denir. Bunlara bazan öznitelik veya alan dendiği de olur, fakat bu kılavuzun amaçları doğrultusunda biz özellik terimini kullanacağız. PHP 7.4 itibariyle, özellikler normal değişken bildiriminin önüne isteğe bağlı (Görünürlük sözcüklerinden biri, language.oop5.static.php veya PHP 8.1.0 itibariyle readonly gibi) bir değiştirici ve ardından isteğe bağlı bir tür belirtimi getirilerek bildirilir. Bu bildirim, bir ilklendirme olarak da yapılabilir; bu durumda sabit bir değerle ilklendirme yapılmalıdır.

Bilginize:

Sınıf özelliklerini bildirmenin artık kullanılmayan bir yolu da, bu değiştiriciler yerine var sözcüğünü kullanmaktır.

Bilginize: Görünürlük sözcüklerinden biri kullanılmadan bildirilen bir özellik public olarak bildirilmiş olur.

Statik olmayan özelliklere, yöntemleri içinden -> (Nesne İşleci): $this->özellik (burada özellik özelliğin ismidir) kullanarak erişilir. Statik özelliklere ise :: (Çift İki nokta imi): self::özellik kullanarak erişilir. Statik ve statik olmayan özellikler arasıdaki fark hakkında daha ayrıntılı bilgi için static Anahtar Sözcüğü bölümüne bakınız.

Yöntem bir nesne bağlamından çağrılıyorsa $this sözde değişkeni sınıf yöntemleri içinde de kullanılabilir. $this, yöntemi çağıran nesnenin değeridir.

Örnek 1 - Özellik bildirimi

<?php
class SimpleClass
{
public
$var1 = 'hello ' . 'world';

public
$var2 = <<<EOD
hello world
EOD;
public
$var3 = 1+2;

// geçersiz özellik bildirimleri:
public $var4 = self::myStaticMethod();
public
$var5 = $myVar;

// geçerli özellik bildirimleri:
public $var6 = myConstant;
public
$var7 = [true, false];

public
$var8 = <<<'EOD'
hello world
EOD;

// Örtük public bildirim:
static $var9;
readonly
int $var10;
var
$var11;
}
?>

Bilginize:

Sınıflar ve nesnelerle çalışan bazı işlevler vardır. Bunlar için Sınıf ve Nesne İşlevleri bölümüne bakınız.

Tür Bildirimleri

PHP 7.4.0 ve sonrasında özellik tanımı callable istisnası ile tür bildirimi içerebilmektedir.

Örnek 2 - Tür ile özellik bildirimi

<?php

class User
{
public
int $id;
public ?
string $name;

public function
__construct(int $id, ?string $name)
{
$this->id = $id;
$this->name = $name;
}
}

$user = new User(1234, null);

var_dump($user->id);
var_dump($user->name);

?>

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

int(1234)
NULL

Tür bildirimli özellikler erişilmeden önce ilklendirilmelidir, aksi takdirde bir Error yavrulanır.

Örnek 3 - Özelliklere erişim

<?php

class Shape
{
public
int $numberOfSides;
public
string $name;

public function
setNumberOfSides(int $numberOfSides): void
{
$this->numberOfSides = $numberOfSides;
}

public function
setName(string $name): void
{
$this->name = $name;
}

public function
getNumberOfSides(): int
{
return
$this->numberOfSides;
}

public function
getName(): string
{
return
$this->name;
}
}

$triangle = new Shape();
$triangle->setName("triangle");
$triangle->setNumberofSides(3);
var_dump($triangle->getName());
var_dump($triangle->getNumberOfSides());

$circle = new Shape();
$circle->setName("circle");
var_dump($circle->getName());
var_dump($circle->getNumberOfSides());
?>

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

string(8) "triangle"
int(3)
string(6) "circle"

Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be accessed before initialization

Salt-okunur Özellikler

PHP 8.1.0 itibariyle, bir özellik readonly ile bildirilebilmekte ve böylece ilklendirmeden sonra özellik üzerinde değişiklik yapılması engellenebilmektedir.

Örnek 4 - Salt-okunur özellik örneği

<?php

class Test {
public readonly
string $prop;

public function
__construct(string $prop) {
// Geçerli ilklendirme
$this->prop = $prop;
}
}
// dolaylı ilklendirme
$test = new Test("foobar");
// Geçerli değerin okunması
var_dump($test->prop); // string(6) "foobar"

// Geçersiz atama. Aynı değer yeniden atanıyor olsa bile geçerli değil.
$test->prop = "foobar";
// Hata: Salt-okunur özellik Test::$prop üzerinde değişiklik yapılamaz
?>

Bilginize:

readonly betimleyicisi sadece özelliklere veri türü bildirimi yapılırken uygulanabilir. Bir salt-okunur özelliği veri türü kısıtlaması olmaksızın bildirmek için mixed türü kullanılabilir.

Bilginize:

Salt-okunur statik özellikler desteklenmemektedir.

Bir salt-okunur özellik yalnızca bir kere, sadece bildirildiği bağlamda ilklendirilebilir ve bunun dışındaki her türlü ilklendirme ya da değişiklik hata ile sonuçlanır (Error istisnası yavrulanır).

Örnek 5 - Salt-okunur özelliklerde hatalı ilklendirme örneği

<?php
class Test1 {
public readonly
string $prop;
}

$test1 = new Test1;
// Özel bağlamı dışında (küresel bağlamda) ilklendirme hatası
$test1->prop = "foobar";
// Error: Cannot initialize readonly property Test1::$prop from global scope
?>

Bilginize:

Salt-okunur özelliklerde öntanımlı değerin açıkça belirtilmesine izin verilmez. Çünkü, salt-okunur bir özelliği bir değerle bildirmek, özünde bir sabitten farksız olduğundan bu yararsızdır.

<?php

class Test {
// Ölümcül hata: Salt-okunur özellik Test::$prop öntanımlı değere sahip olamaz
public readonly int $prop = 42;
}
?>

Bilginize:

Salt-okunur özellikler ilklendirildikten sonra unset() gibi bir işlevle yok edilemez. Bu ancak, özelliğin bildirildiği bağlamda, ilklendirilmeden önce mümkündür.

Aşağıdaki gibi düz atamalarla yapılmayan değişiklikler de Error istisnasına yol açar:

<?php

class Test {
public function
__construct(
public readonly
int $i = 0,
public readonly array
$ary = [],
) {}
}

$test = new Test;
$test->i += 1;
$test->i++;
++
$test->i;
$test->ary[] = 1;
$test->ary[0][] = 1;
$ref =& $test->i;
$test->i =& $ref;
byRef($test->i);
foreach (
$test as &$prop);
?>

Bununla birlikte salt-okunur özellikler, içerik değişikliğini engellemez. Nesneler (veya özkaynaklar) salt-okunur özelliklerde saklansa bile içerikleri değiştirilebilir:

<?php

class Test {
public function
__construct(public readonly object $obj) {}
}

$test = new Test(new stdClass);
// Geçerli içerik değişikliği.
$test->obj->foo = 1;
// Geçersiz atama
$test->obj = new stdClass;
?>

Dinamik özellikler

Bir nesnede mevcut olmayan bir özelliğe atama yapılmaya çalışılırsa PHP olmayan özelliği otomatik olarak oluşturmaya çalışır. Böyle dinamik olarak oluşturulan bir özellik sınıfın yalnızca bu nesnesinde kullanılabilir.

Uyarı

PHP 8.2.0 ve sonrasında dinamik özelliklerin kullanımı önerilmemektedir. Özelliğe atama yapmadan önce bildirilmesi önerilir. Keyfi özellik isimlerini işleme sokabilmek için sınıfın sihirli __get() ve __set() yöntemlerini gerçeklemesi gerekir. Son çare olarak, sınıf #[\AllowDynamicProperties] özelliği ile imlenebilir.

add a note

User Contributed Notes 6 notes

up
342
Anonymous
11 years ago
In case this saves anyone any time, I spent ages working out why the following didn't work:

class MyClass
{
private $foo = FALSE;

public function __construct()
{
$this->$foo = TRUE;

echo($this->$foo);
}
}

$bar = new MyClass();

giving "Fatal error: Cannot access empty property in ...test_class.php on line 8"

The subtle change of removing the $ before accesses of $foo fixes this:

class MyClass
{
private $foo = FALSE;

public function __construct()
{
$this->foo = TRUE;

echo($this->foo);
}
}

$bar = new MyClass();

I guess because it's treating $foo like a variable in the first example, so trying to call $this->FALSE (or something along those lines) which makes no sense. It's obvious once you've realised, but there aren't any examples of accessing on this page that show that.
up
82
anca at techliminal dot com
8 years ago
You can access property names with dashes in them (for example, because you converted an XML file to an object) in the following way:

<?php
$ref
= new StdClass();
$ref->{'ref-type'} = 'Journal Article';
var_dump($ref);
?>
up
67
Anonymous
13 years ago
$this can be cast to array. But when doing so, it prefixes the property names/new array keys with certain data depending on the property classification. Public property names are not changed. Protected properties are prefixed with a space-padded '*'. Private properties are prefixed with the space-padded class name...

<?php

class test
{
public
$var1 = 1;
protected
$var2 = 2;
private
$var3 = 3;
static
$var4 = 4;

public function
toArray()
{
return (array)
$this;
}
}

$t = new test;
print_r($t->toArray());

/* outputs:

Array
(
[var1] => 1
[ * var2] => 2
[ test var3] => 3
)

*/
?>

This is documented behavior when converting any object to an array (see </language.types.array.php#language.types.array.casting> PHP manual page). All properties regardless of visibility will be shown when casting an object to array (with exceptions of a few built-in objects).

To get an array with all property names unaltered, use the 'get_object_vars($this)' function in any method within class scope to retrieve an array of all properties regardless of external visibility, or 'get_object_vars($object)' outside class scope to retrieve an array of only public properties (see: </function.get-object-vars.php> PHP manual page).
up
28
zzzzBov
13 years ago
Do not confuse php's version of properties with properties in other languages (C++ for example). In php, properties are the same as attributes, simple variables without functionality. They should be called attributes, not properties.

Properties have implicit accessor and mutator functionality. I've created an abstract class that allows implicit property functionality.

<?php

abstract class PropertyObject
{
public function
__get($name)
{
if (
method_exists($this, ($method = 'get_'.$name)))
{
return
$this->$method();
}
else return;
}

public function
__isset($name)
{
if (
method_exists($this, ($method = 'isset_'.$name)))
{
return
$this->$method();
}
else return;
}

public function
__set($name, $value)
{
if (
method_exists($this, ($method = 'set_'.$name)))
{
$this->$method($value);
}
}

public function
__unset($name)
{
if (
method_exists($this, ($method = 'unset_'.$name)))
{
$this->$method();
}
}
}

?>

after extending this class, you can create accessors and mutators that will be called automagically, using php's magic methods, when the corresponding property is accessed.
up
0
bernard dot dautrevaux at ac6 dot fr
1 month ago
It's not specified above, but, at least in PHP-8, properties declared with the (deprecated but still widely used) keyword 'var' are declared as 'protected', not as 'public' as they used to be before the visibility keywords were introduced.
up
-3
kchlin dot lxy at gmail dot com
1 year ago
From PHP 8.1
It's easy to create DTO object with readonly properties and promoting constructor
which easy to pack into a compact string and covert back to a object.
<?php
# Conversion functions.
# Pack object into a compack JSON string.
function cvtObjectToJson( object $poObject ): string
{
return
json_encode( array_values( get_object_vars( $poObject )));
}

# Unpack object from a JSON string.
function cvtJsonToObject( string $psClass, string $psString ): object
{
return new
$psClass( ...json_decode( $psString ));
}

# DTO example class.
final class exampleDto
{
final public function
__construct(
public readonly
int $piInt,
public readonly ?
int $pnNull,
public readonly
float $pfFloat,
public readonly
string $psString,
public readonly array
$paArray,
public readonly
object $poObject,
){}
}

# Example with export only public properties of given object.
$exampleDtoO = new exampleDto( 1, null, .3, 'string 4', [], new stdClass() );
$stringJson = cvtObjectToJson( $exampleDtoO );// [1,null,0.3,"string 4",[],{}]
$objectO = cvtJsonToObject( exampleDto::class, $stringJson );

# Check and var_dump variables.
echo $exampleDtoO == $objectO
? 'Objects equal, but not identical.'. PHP_EOL
: 'Objects not equal neither identical.'. PHP_EOL
;
var_dump($exampleDtoO, $stringJson, $objectO);

# Output
/*
Objects equal, but not identical
object(exampleDto)#6 (6) {
["piInt"]=>
int(1)
["pnNull"]=>
NULL
["pfFloat"]=>
float(0.3)
["psString"]=>
string(8) "string 4"
["paArray"]=>
array(0) {
}
["poObject"]=>
object(stdClass)#7 (0) {
}
}
string(29) "[1,null,0.3,"string 4",[],{}]"
object(exampleDto)#8 (6) {
["piInt"]=>
int(1)
["pnNull"]=>
NULL
["pfFloat"]=>
float(0.3)
["psString"]=>
string(8) "string 4"
["paArray"]=>
array(0) {
}
["poObject"]=>
object(stdClass)#9 (0) {
}
}
*/
To Top