Dizeye göre PHP sınıfı özelliğini edinin


139

Bir dize dayalı bir PHP bir özelliği nasıl alabilirim? Ben arayacağım magic. Öyleyse nedir magic?

$obj->Name = 'something';
$get = $obj->Name;

şöyle olurdu ...

magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');

Yanıtlar:


241

Bunun gibi

<?php

$prop = 'Name';

echo $obj->$prop;

Veya sınıf üzerinde denetiminiz varsa, ArrayAccess arabirimini uygulayın ve bunu yapın

echo $obj['Name'];

İkinci seçeneği birincisine göre kullanmanın herhangi bir faydası var mı?
Clox

2
@Clox Genellikle, değişkenleri dizi benzeri bir şekilde tüketen mevcut bir sisteminiz varsa, ancak nesnelerin sunduğu esnekliği ve gücü istiyorsanız, ikincisini kullanmanın ana yararı. Bir sınıf ve yineleyici arabirimlerinden biri uygulanırsa ArrayAccess, Countableçoğunlukla normalden ayırt edilemezarray()
Peter Bailey

158

Ara değişken oluşturmadan özelliğe erişmek istiyorsanız, {}gösterimi kullanın :

$something = $object->{'something'};

Bu, özellik adını bir döngüde oluşturmanıza da olanak tanır:

for ($i = 0; $i < 5; $i++) {
    $something = $object->{'something' . $i};
    // ...
}

8
Bir dizi değerine erişmek istiyorsanız tek yol budur $this->{$property}[$name], aksi takdirde $this->$property[$name]bir hata verir
goyote

@goyote: Değerlere ve PHP sürümüne bağlıdır. 5.3'te hala geçerli bir PHP sözdizimi olduğundan bir "hata" yerine özellik bulunamadığından bir E_NOTICE tetikler. Bu $this->$property[$name]bir hata olabilir, ancak aslında başarılı olabilir. $namesessizce bir tamsayıya dökülür. Sayısal olmayan bir dize olması durumunda 0. Ardından , değerinin bu dize dizini$property özellik adı olarak kullanılır. Eğer $propertydeğer "abc" tutar, o zaman bu özellik sevk edecektir $this->a(index 0). Böyle bir özellik varsa, bu başarılı olacaktır.
MrWhite

@goyote: Bununla birlikte, PHP 5.4'te, sayısal olmayan bir dize dizini 0 tamsayısına sessizce aktarılmaz, bir E_WARNING tetikler.
MrWhite

13

Sorduğunuz şey Değişken Değişkenler . Tek yapmanız gereken dizenizi bir değişkende saklamak ve dizine şu şekilde erişmek:

$Class = 'MyCustomClass';
$Property = 'Name';
$List = array('Name');

$Object = new $Class();

// All of these will echo the same property
echo $Object->$Property;  // Evaluates to $Object->Name
echo $Object->{$List[0]}; // Use if your variable is in an array

3
Değişken değişkenler başka bir şeydir.
furlafur Ücreti

2
Soru, ad bir dizgide (değişken) bulunduğunda bir sınıf özelliğinin (değişken) nasıl alınacağıdır. Yoksa soruyu yanlış mı okudum?
matpie

8

Böyle bir şey mi? Test etmedim ama iyi çalışmalı.

function magic($obj, $var, $value = NULL)
{
    if($value == NULL)
    {
        return $obj->$var;
    }
    else
    {
        $obj->$var = $value;
    }
}

2
+1, nesne özelliklerinin dizeler kullanılarak erişilebileceğini bilmiyordu.
Marco Demaio

5

Özellik adını bir değişkende saklayın ve özelliğe erişmek için değişkeni kullanın. Bunun gibi:

$name = 'Name';

$obj->$name = 'something';
$get = $obj->$name;


4

Basittir, $ obj -> {$ obj-> Name} küme parantezleri özelliği değişken bir değişken gibi sarar.

Bu bir üst arama oldu. Ama bu $ kullanarak kullanıyorum sorum çözmedi. Durumumun kıvırcık dirseği kullanması da yardımcı oldu ...

Code Igniter ile örnek al örneği

bir üst sınıf örneğiyle bir şey adı verilen kaynak kitaplığı sınıfında

$this->someClass='something';
$this->someID=34;

ebeveyn örneğiyle de başka bir sınıftan kaynak alması gereken kütüphane sınıfı

echo $this->CI->{$this->someClass}->{$this->someID};

2

Bir ek olarak: Bu şekilde, başka türlü kullanılamayacak adlara sahip özelliklere erişebilirsiniz

$ x = yeni StdClass;

$ prop = 'a b'; $ x -> $ prop = 1; $ x -> {'x y'} = 2; var_dump ($ x);

nesne (stdClass) # 1 (2) {
  ["a b"] =>
  int (1)
  ["x y"] =>
  int (2)
}
(yapmanız gerekmiyor, ancak yapmanız gerekiyorsa).
Daha meraklı şeyler yapmak istiyorsanız, yansımanın içine bakmalısınız.


1

Başka birinin derinliği bilinmeyen derin bir özellik bulmak istemesi durumunda, tüm çocukların bilinen tüm özelliklerini gözden geçirmeye gerek kalmadan aşağıdakileri buldum.

Örneğin, $ Foo-> Bar-> baz veya $ Foo-> baz veya $ Foo-> Bar-> Baz-> dave'yi bulmak için burada $ path 'foo / bar / baz' gibi bir dizedir.

public function callModule($pathString, $delimiter = '/'){

    //split the string into an array
    $pathArray = explode($delimiter, $pathString);

    //get the first and last of the array
    $module = array_shift($pathArray);
    $property = array_pop($pathArray);

    //if the array is now empty, we can access simply without a loop
    if(count($pathArray) == 0){
        return $this->{$module}->{$property};
    }

    //we need to go deeper
    //$tmp = $this->Foo
    $tmp = $this->{$module};

    foreach($pathArray as $deeper){
        //re-assign $tmp to be the next level of the object
        // $tmp = $Foo->Bar --- then $tmp = $Bar->baz
        $tmp = $tmp->{$deeper};
    }

    //now we are at the level we need to be and can access the property
    return $tmp->{$property};

}

Ve sonra şöyle bir şeyle arayın:

$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);

0

İşte benim girişimim. Kullanılmayan bir üye oluşturmaya veya üye almaya çalışmadığınızdan emin olarak yerleşik bazı yaygın 'aptallık' denetimleri vardır.

Bu 'property_exists' kontrollerini sırasıyla __set ve __get'e taşıyabilir ve doğrudan magic () içinde çağırabilirsiniz.

<?php

class Foo {
    public $Name;

    public function magic($member, $value = NULL) {
        if ($value != NULL) {
            if (!property_exists($this, $member)) {
                trigger_error('Undefined property via magic(): ' .
                    $member, E_USER_ERROR);
                return NULL;
            }
            $this->$member = $value;
        } else {
            if (!property_exists($this, $member)) {
                trigger_error('Undefined property via magic(): ' .
                    $member, E_USER_ERROR);
                return NULL;
            }
            return $this->$member;
        }
    }
};

$f = new Foo();

$f->magic("Name", "Something");
echo $f->magic("Name") , "\n";

// error
$f->magic("Fame", "Something");
echo $f->magic("Fame") , "\n";

?>

0

Bu işlevin yaptığı şey, özelliğin çocuğunun herhangi bir sınıfında var olup olmadığını kontrol eder ve eğer öyleyse değeri alırsa aksi halde null değerini döndürür. Şimdi özellikler isteğe bağlı ve dinamik.

/**
 * check if property is defined on this class or any of it's childes and return it
 *
 * @param $property
 *
 * @return bool
 */
private function getIfExist($property)
{
    $value = null;
    $propertiesArray = get_object_vars($this);

    if(array_has($propertiesArray, $property)){
        $value = $propertiesArray[$property];
    }

    return $value;
}

Kullanımı:

const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';

$configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY);

-6
$classname = "myclass";
$obj = new $classname($params);

$variable_name = "my_member_variable";
$val = $obj->$variable_name; //do care about the level(private,public,protected)

$func_name = "myFunction";
$val = $obj->$func_name($parameters);

neden edit: before: using eval (evil) sonra: hiçbir eval hiç. bu dilde yaşlı olmak.


Bu çok kötü bir tavsiye, eval () işlevi çok tehlikeli bir araçtır ve sizi enjeksiyon saldırılarına karşı oldukça savunmasız bırakacaktır. blog.highub.com/php/php-core/php-eval-is-evil size bazı bilgiler vermelidir.
ridecar2

3
Bu yanıtı silerseniz bir rozetiniz olur!
Thermech
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.