2014-12-10 1 views
1

У меня есть класс под названием adminItems в пределах adminitems.class.php. Я пытаюсь включить одну из функций этого класса в xmlParser::someName() в пределах xmlParser.class.php.Как использовать функцию другого класса в текущем классе

Как это:

require_once("adminitems.class.php"); 
$obj = new adminitems(); 

class xmlParser 
{ 
    function someName() 
    { 
     $obj->addAds(); // addAds is within adminItems object 
    } 
} 
` 

Является ли это правильный способ сделать это?

+4

«Инъекция зависимостей» – HamZa

+1

Вам понадобится объект 'class1', предположим' A', а затем в 'classB' использовать его как' $ b = new A(); $ b-> MethodFromClassA(); 'Или использовать наследование. –

+3

Остановите добавление суффикса ".class". Что вы будете делать, когда вам потребуется автозагрузка интерфейса? О, да, кстати. Узнайте, как сделать автозагрузку. –

ответ

5

Не используйте расширяет просто, чтобы получить дополнительную функциональность. Это запах кода и подразумевает, что xmlParseris-aadminItems который, очевидно, нет. Кроме того, в будущем вы не сможете продолжить расширение, потому что PHP не имеет множественного наследования. Выберите composition over inheritance, как показано на этом примере.

Использование Зависимость от инъекции. Инвертируйте управление своими объектами так, чтобы они не зависели друг от друга: см. Inversion on Control.

class xmlParser 
{ 
    /** 
    * @var adminItems 
    */ 
    protected $adminItems; 

    /** 
    * @constructor 
    * 
    * @param adminItems $adminItems 
    */ 
    public function __construct(adminItems $adminItems) 
    { 
     $this->adminItems = $adminItems; 
    } 

    /** 
    * Whatever this does... 
    */ 
    function someName() 
    { 
     $this->adminItems->addAds(); 
    } 
} 
` 

Вам нужно, внешние по отношению к классам создаваемым, свяжите их вместе, как это. Вы передаете adminItemsвxmlParser, а затем используйте его, как вам нужно. Это называется Dependency Injection и это то, что вы можете делать на всех объектно-ориентированных языках, а не только на php.

Вы могли бы использовать вышеупомянутый объект API, как это:

$adminItems = new adminItems; 
$xmlParser = new xmlParser($adminItems); 
$xmlParser->somName(); 

Действительно просто. Ваши объекты (думают о них как повторно используемые библиотеки) не должны зависеть от других объектов, кроме как с помощью конструктора или метода, поэтому вы можете их заменить, что приведет к тестируемому и чистому очищению кода.

Кроме того, я призываю вас, чтобы взглянуть на следующие полезные ссылки:

  • PSR-2 для именования:
    • Использование XmlParser вместо xmlParser для имен классов
  • PSR-4 для автозагрузки:
    • Узнать, как использовать composer для создания своих автозагрузки файлов для вас
    • Узнайте, как ваши файлы имеют 1: отображение 1 со структурой каталогов
    • Узнайте, как вы только когда-либо нужно использовать включаемый раз в проекте
+0

Вы можете добавить PSR-4, поскольку он, по-видимому, превзошел PSR-0. Это хороший ответ. – Rangad

+0

@ Rangad Согласен, я сделаю это сейчас. – Jimbo

+0

@jimbo благодарю вас за ответ очень описательный. С тех пор я попытаюсь написать классы таким образом. – Vikram

-5

Практически правильный метод - но $ obj не входит в объем. Некрасивое решение было бы delcare его в глобальном масштабе ...

require_once("adminitems.class.php"); 
global $obj; 
$obj = new adminitems(); 

class xmlParser 
{ 

function someName() 
{ 
    global $obj; 
    $obj->addAds(); 

} 

Вы можете уточнить этот подход с использованием пространств имен, но правильный ответ, вероятно, передать ссылку в сферу, например,

function someName($obj) 
{ 
    $obj->addAds(); 

} 
+1

Здесь происходит очень партийное голосование. 4 downvotes и только один комментарий (теперь удален)? – symcbean

+1

Большая часть SO рассмотрит «глобальное» ключевое слово evil. И в тех случаях, когда другое решение явно более чистое, кажется, оправдано, что оправдано. – Rangad

+0

Нет ничего плохого в этом ответе, проблема в том, что некоторые пользователи навязывают свой путь решения вещей, я имею в виду, когда глобальные переменные становятся злыми. – Danijel

-5

Вы можете использовать другие функции класса за счет расширения родительского класса

class xmlParser extends adminitems{ 
    function someName(){ 
     $obj->addAds(); 
} 
} 
2

Если класс B нужна функция класса A, у вас есть много решений в PHP:

1. Наследование

Расширить класс A классом B. Класс B сможет получить доступ к общедоступному и защищенному методу класса A.

class B extends A { 
} 

Я бы не рекомендовал это. В ООП очень плохо использовать наследование только для использования одной функции класса, которая не имеет такой же ответственности.

2. Черты характера

Использование traits (с PHP5.4.0):

trait factoredMethods { 
    function getX() { /*...*/ } 
    function setY() { /*...*/ } 
} 

class A { 
    use factoredMethods; 
} 

class B { 
    use factoredMethods; 
} 

Это может быть интересным решением в некоторых случаях, но это часто пятно на плохой концепции.

3. Состав

Наилучшим вариантом является использование композиции. B использует A:

class A { 
} 

class B { 
    private $a; 

    public function __construct(A $a) { 
     $this->a = $a; 
    } 
} 

$a = new A(); 
$b = new B($a); 

Конечно, метод, который вы хотите использовать в A должен быть общедоступным. Я настоятельно рекомендую использовать интерфейс между A и B, чтобы иметь низкое сцепление.

+0

Я бы переместил композицию на верх. Это должно быть «решение по умолчанию». – ThW

+1

Я бы избегал черт - особенно как своего рода «множественное наследование» - они в основном статический доступ: [интересное чтение] (http://www.whitewashing.de/2013/04/12/traits_are_static_access.html). В частности, комментарии пользователей тоже (они идут немного глубже). – Jimbo

+0

@ThW Если вы видите лучшее решение в первую очередь, то в чем смысл чтения других решений (и знать, почему они плохие)? – Gnucki

Смежные вопросы