Ben bir PHP sınıfa kodu içerebilir?

5 Cevap php

Ben bir PHP sınıfı yapmak istiyorum, Myclass.php Diyelim ki. Şimdi o sınıfın içinde ben sadece sınıf kendisi ve bazı örnek değişkenleri tanımlamak istiyorum. Ama bütün yöntemleri bir Myclass_methods.php dosyadan gelmelidir. Ben sadece sınıf vücuda bu dosyayı dahil edebilir?

Ben bu ayırmak istiyorum neden iyi nedenleri var. Bütün diğer şeyler bakir kalması gerekir iken Kısacası, ben bir sınıfın iş mantığını değiştirmek hangi bir arkaplana sahip olacak. Sistem benim için tüm ORM ve diğer şeyler korur.

Ama bu kötü bir fikir ise, bu iş mantığı (yani, bu durumda kullanıcı-tanımlı yöntemleri) düzenledikten sonra bütün sınıf dosyasını yeniden oluşturmak için daha iyi olabilir.

Performans soru: bir istek sırasında Myclass.php sadece bir kez dahil edilirse, aslında Myclass_methods.php da sadece bir kez dahil edilmesi gerektiğini söyledi. Yanlış olabilir. Uzmanlar?

5 Cevap

No. You cannot include files in the class body.
In a file defining a class, you may only include files in a method body or outside the class body.

Açıklamasından ben bunu istiyorum almak:

<?php // MyClass.php
class MyClass
{
    protected $_prop;
    include 'myclass-methods.php';
}

<?php // myclass-methods.php
public function myMethod()
{
   $this->$_prop = 1;
}

Bu kodu çalıştırmadan neden olacaktır

Parse error: syntax error, unexpected T_INCLUDE, expecting T_FUNCTION

Ne olsa mümkün bu

<?php // MyClass.php
class MyClass
{
    protected $_prop;
    public function __construct() // or any other method
    {
        include 'some-functions.php';
        foo($b); // echoes 'a';
    }
}

<?php // some-functions.php
$b = 'a';
function foo($str)
{
   echo $str;
}

Bu şekilde yaparak, yöntemi kapsamında değil, sınıf kapsamı içine dahil dosyasının içeriğini ithal edecek. Sen dahil dosyasındaki işlevleri ve değişkenleri içerir, ama yöntemleri olabilir. Sen could but should not içine de tüm komut koymak ve örneğin, yöntemi ne değiştirebilir

<?php // MyClass.php
    // ...
    public function __construct($someCondition)
    {
        // No No Code here
        include ($someCondition === 'whatever') ? 'whatever.php' : 'default.php';
    }
    // ...

<?php // whatever.php
    echo 'whatever';

<?php // default.php
    echo 'foo';

Ancak, sınıf farklı bir davranış sergilemek için bu şekilde yama OOP bunu nasıl değildir. Bu sadece düz yanlış ve gözlerinden kan yapmalıdır.

Dinamik davranışı değiştirmek istediğiniz beri sınıfını genişleterek (neden aşağıya bakınız) da iyi bir seçenek değildir. Ne gerçekten yapmak isteyeceğiniz bir interface yazmak ve sınıf nesneleri kullanma uygun yöntemleri mevcuttur emin nedenle, bu arabirimi uygulayan olun. Bu Strategy Pattern denir ve bu gibi çalışır:

<?php // Meowing.php 
interface Meowing
{
    public function meow();
}

Şimdi tüm meowing Davranışlar yani bir miyav yöntem olan, itaat etmeliyiz sözleşme var. Sonraki Meowing Davranış tanımlamak:

<?php // RegularMeow.php
class RegularMeow implements Meowing
{
    public function meow()
    {
        return 'meow';
    }
}

Şimdi kullanmak için kullanın:

<?php // Cat.php
class Cat
{
    protected $_meowing;

    public function setMeowing(Meowing $meowing)
    {
        $this->_meowing = $meowing;
    }

    public function meow()
    {
        $this->_meowing->meow()
    }
}

Ekleyerek TypeHint setMeowing için Meowing, sen geçti param Meowing arabirimini uygulayan emin olun. Başka bir Meowing Davranış açıklayalım:

<?php // LolkatMeow.php
class LolkatMeow implements Meowing
{
    public function meow()
    {
        return 'lolz xD';
    }
}

Şimdi, kolayca bu gibi davranışları gistirilip:

<?php
require_once 'Meowing.php';
require_once 'RegularMeow.php';
require_once 'LolkatMeow.php';
require_once 'Cat.php';

$cat = new Cat;
$cat->setMeowing(new RegularMeow);
echo $cat->meow; // outputs 'meow';
// now to change the behavior
$cat->setMeowing(new LolkatMeow);
echo $cat->meow; // outputs 'lolz xD';

Aynı zamanda bir abstract BaseCat ve miyav yöntemi tanımlarken ve o somut RegularCat ve Lolkat sınıflar türetmek inheritance ile yukarıdaki çözmüş olsa da, size ulaşmak istediğiniz göz önünde bulundurmanız gerekir . Lütfen kediler miyav biçimini asla değişmeyecek, devam edin ve devralma kullanmak, ancak RegularCat ve Lolkat keyfi meows yapmak mümkün olması gerekiyordu ise, o Strateji desen kullanın.

Daha design patterns PHP, bu kaynakları kontrol için:

Bir daha mantıklı bir yaklaşım gibi görünüyor - o ilgili taban işlevselliği ile çekirdek sınıfı oluşturmak ve daha sonra gerekli yöntemleri ile bu uzatmak için bir fikir olmayabilir.

Can I just include that file into the class body?

Hayır.

Bu problem en iyi verileri içeren yöntemler, alt sınıfları ve dinamik sınıf yükleme içeren bir temel sınıf kullanılarak çözülebilir değil bu yüzden ben çok net değilim diyerek başlayacağız. Ben iyi bir nedeni var kabul edeceğiz.

Sağlayıcınız PHP 5.4 destekliyorsa kez sen özellikleri kullanarak istediğinizi yapabilirsiniz.

Kod Dosya:

if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');

class Pet {
  use PetSounds;
}

$myPet = new Pet();
$myPet->speak();

Dosya cat.php

trait PetSounds {
  function speak() { echo 'meow'; }
}

Dog.php Dosya

trait PetSounds {
  function speak() { echo 'woof'; }
}

Hatta temizleyici, hem de dosyaları aynı içerir adlandırma farklı altdizinlere koyarak ve set_include_path kullanarak () veya aralarında seçmek için bir __ autoload () işlevi tanımlayarak yapabiliriz. Ama dediğim gibi, bu aynı sorun devralmayı kullanarak daha iyi çözülebilir. Örneğin üç saç tipleri ile renkleri beş türlü hayvan dört çeşit varsa, olsa bir çoklu miras tip sorun var ve 60 farklı sınıfların her biri için yöntemler farklı bir kombinasyonuna ihtiyacınız varsa, bu doğru çözümdür .

5.4 şu anda (2012/02/24 itibariyle) sadece bir Release Candidate ve hatta bir kez yayımlanan en barındıran aylarca destek değil - benim onlar destek vereceklerini önce yayımlanan 5,3 sonra 18 ay sürdü. O zamana kadar tamamen ayrı ve eksiksiz sınıf dosyaları yazmak gerekir. Ancak akılda özellikleri için nihai bir değişiklik ile sınıfları biçimlendirebilirsiniz.

Şu anda kısmen sihirli yöntemler kullanarak istediklerini almak ve mevcut olduğunda özellikleri kolay bir yükseltme olabilir.

Kod Dosya:

if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');

class Pet {
  public function __call($name, array $arguments)
  {
    array_unshift($arguments, $this);
    return call_user_func_array("TraitFunc_$name", $arguments);
  }
}

$myPet = new Pet();
$myPet->speak();

Dosya cat.php

function TraitFunc_speak(Pet $that) { echo 'meow'; }

Dog.php Dosya

function TraitFunc_speak(Pet $that) { echo 'woof'; }

O sizin fonksiyonları özel ve korunan sınıf özellikleri ve yöntemleri erişemez ve bu tür __ get gibi sihirli yöntemler () sağlamak için bu yöntemi kullanamazsınız ancak sınırlıdır. Özellikleri bu sınırlamalar hem çözecektir.

PHP5.4 serbest beri dynamic objects bu gibi oluşturabilirsiniz: https://github.com/ptrofimov/jslikeobject

Ama bu scarcely en iyi uygulamadır.