Berry'nin cevabını genişletmek gerekirse, erişim düzeyini korumalı olarak ayarlamak, __get ve __set'in açıkça beyan edilen özelliklerle (en azından sınıfın dışından erişildiğinde) kullanılmasına ve hızın oldukça yavaş olmasına izin verir, başka bir sorudan bir yorum alıntılayacağım bu konuda ve yine de kullanmak için bir durum oluşturun:
__Get'in özel bir get işlevine göre daha yavaş olduğunu (aynı şeyleri yapıyor) kabul ediyorum, bu __get () için 0.0124455 ve bu 0.0024445 10000 döngüden sonra özel get () içindir. - Melsi 23 Kasım 2012 saat 22:32 En iyi uygulama: PHP Sihir Yöntemleri __set ve __get
Melsi'nin testlerine göre, oldukça yavaş, yaklaşık 5 kat daha yavaştır. Bu kesinlikle çok daha yavaştır, ancak testlerin, bu yöntemle bir mülke hala saniyenin yaklaşık 1 / 100'ü içinde döngü yinelemesi için süreyi sayarak 10.000 kez erişebileceğinizi gösterdiğini unutmayın. Tanımlanan gerçek get ve set yöntemlerine kıyasla önemli ölçüde daha yavaştır ve bu bir eksikliktir, ancak genel şemada, 5 kat daha yavaş bile asla yavaş değildir.
İşlemin hesaplama süresi hala ihmal edilebilir düzeydedir ve gerçek dünya uygulamalarının% 99'unda dikkate alınmaya değmez. Gerçekten kaçınılması gereken tek zaman, mülklere tek bir istekte 10.000'den fazla kez erişeceğiniz zamandır. Yüksek trafikli siteler, uygulamalarını çalışır durumda tutmak için birkaç sunucu daha atmayı göze alamazlarsa gerçekten yanlış bir şey yapıyorlar. Erişim oranının sorun haline geldiği yüksek trafikli bir sitenin altbilgisindeki tek satırlık bir metin reklam, muhtemelen bu metin satırına sahip 1.000 sunucudan oluşan bir çiftlik için ödeme yapabilir. Son kullanıcı, uygulamanızın mülk erişimi saniyenin milyonda biri kadar sürdüğü için, sayfanın yüklenmesinin bu kadar uzun sürdüğünü merak ederek asla parmaklarına dokunmayacaktır.
Bunu .NET'te bir arka plandan gelen bir geliştirici olarak söylüyorum, ancak tüketiciye görünmeyen alma ve ayarlama yöntemleri .NET'in icadı değil. Onlar sadece onlar olmadan özellik değildirler ve bu sihirli yöntemler PHP'nin geliştiricisinin kendi özellik sürümlerini "özellikler" olarak adlandırması için bile tasarruf etme yetkisidir. Ayrıca, PHP için Visual Studio uzantısı, bu hile göz önünde bulundurularak, korumalı özelliklerle intellisense'i desteklediğini düşünüyorum. Bu şekilde sihirli __get ve __set yöntemlerini kullanan yeterli geliştiriciyle, PHP geliştiricilerinin, geliştirici topluluğunun ihtiyaçlarını karşılamak için yürütme süresini ayarlayacağını düşünüyorum.
Düzenleme: Teoride, korunan mülkler çoğu durumda işe yarayacak gibi görünüyordu. Pratikte, sınıf tanımı ve genişletilmiş sınıflar içindeki özelliklere erişirken birçok kez alıcılarınızı ve ayarlayıcılarınızı kullanmak isteyeceğiniz ortaya çıkıyor. Daha iyi bir çözüm, diğer sınıfları genişletirken temel sınıf ve arabirimdir; bu nedenle, temel sınıftan birkaç kod satırını uygulama sınıfına kopyalayabilirsiniz. Projemin temel sınıfıyla biraz daha fazlasını yapıyorum, bu yüzden şu anda sağlamak için bir arayüzüm yok, ancak burada, özellikleri kaldırmak ve taşımak için yansımayı kullanarak sihirli özellik alma ve ayarlama ile test edilmemiş soyulmuş sınıf tanımı var. korumalı bir dizi:
class Component {
protected $properties = array();
public function __get($name) {
$caller = array_shift(debug_backtrace());
$max_access = ReflectionProperty::IS_PUBLIC;
if (is_subclass_of($caller['class'], get_class($this)))
$max_access = ReflectionProperty::IS_PROTECTED;
if ($caller['class'] == get_class($this))
$max_access = ReflectionProperty::IS_PRIVATE;
if (!empty($this->properties[$name])
&& $this->properties[$name]->class == get_class()
&& $this->properties[$name]->access <= $max_access)
switch ($name) {
default:
return $this->properties[$name]->value;
}
}
public function __set($name, $value) {
$caller = array_shift(debug_backtrace());
$max_access = ReflectionProperty::IS_PUBLIC;
if (is_subclass_of($caller['class'], get_class($this)))
$max_access = ReflectionProperty::IS_PROTECTED;
if ($caller['class'] == get_class($this))
$max_access = ReflectionProperty::IS_PRIVATE;
if (!empty($this->properties[$name])
&& $this->properties[$name]->class == get_class()
&& $this->properties[$name]->access <= $max_access)
switch ($name) {
default:
$this->properties[$name]->value = $value;
}
}
function __construct() {
$reflected_class = new ReflectionClass($this);
$properties = array();
foreach ($reflected_class->getProperties() as $property) {
if ($property->isStatic()) { continue; }
$properties[$property->name] = (object)array(
'name' => $property->name, 'value' => $property->value
, 'access' => $property->getModifier(), 'class' => get_class($this));
unset($this->{$property->name}); }
$this->properties = $properties;
}
}
Kodda herhangi bir hata varsa özür dilerim.