ООП динамическое добавление методов

Статус
В этой теме нельзя размещать новые ответы.

CrashX

В прошлом XSiteCMS
Регистрация
6 Июн 2008
Сообщения
682
Реакции
114
ООП динамическое добавление методов
может кто делал ранее
нужно скажем есть свойство
keyword и нужно его сделать методом и назначить набор свойст вида
get,set,generate,clear
щас имею вид
Код:
$engine->document->keySet();
$engine->document->keyGet();
$engine->document->keyGen();
а хочу
внутри должно быть
Код:
private $value=array();
$engine->document->key->generate();
$engine->document->key->get();
$engine->document->key->set();

набор действий стандартных одинковый это вернуть ключ, добавить ключ, создать, очистить.

как нибудь можно скажем имея шаблон расширять нужные свойства до объектов

зачем это нужно ? да тупо для удобства
тк мне удобнее обращаться к некоторому свойству не трогая его само что бы голова не болела что могу его испортить

такую фигню хочу добавить массово многим объектам
 
ну так сделайте внутреннюю переменную key каким-то классом (на подобии паттерна Registry ) внутри которого будут реализованы все эти методы get,set,generate,clear

или я чего-то не то понял?
 
ну так сделайте внутреннюю переменную key каким-то классом (на подобии паттерна Registry ) внутри которого будут реализованы все эти методы get,set,generate,clear

или я чего-то не то понял?
То что ТС хочет реализовать, называется метапрограммирование, которое в PHP отсутствует. Можно попробывать сделать эмуляцию метапрограммирования через создание анонимных лямбда-функций либо попробовать поиграть с дополнением php runkit.
 
в общем как хотел не смог сделал проще
сделал для каждого метода, который нужно расширить и расширил в конструкторе.
благо еще раз подумал и сделал там где действительно нужно скрыть
например

PHP:
<?php


/**
 * Класс документа
 */
class Document {

  var $version = 0.01;
  public $title = null;
  public $description = null;
  public $keyword = null;
  public $style = null;
  public $script = null;
  public $header = null;

  public function __construct() {
    $this->keyword = new Keyword();
    $this->description = new Description();
    $this->title = new Title();
  }

  /**
   * @global Engine $engine
   */
  function headers() {
    global $engine;
    header("Content-Type: text/html; charset=" . $engine->language->get('CHARSET'));
    header("Cache-Control: no-store, no-cache, must-revalidate");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    header("Expires: " . gmdate("D, d M Y H:i:s", 0) . " GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("X-Powered-By: XSiteCMS ");
  }

  /**
   * @global Engine $engine
   * @return <type>
   */
  function meta() {
    global $engine;
    return '<meta charset=' . $engine->language->get('CHARSET') . ' />
  <meta http-equiv="content-type" content="text/html; charset=' . $engine->language->get('CHARSET') . '" />
  <meta name="title" content="' . $this->title->get() . '" />
  <meta name="keywords" content="' . $this->keyword->get() . '" />
  <meta name="description" content="' . $this->description->get() . '" />
  <meta name="abstract" content="' . $this->description->get() . '" />
  <meta name="generator" content="' . GENERATOR . '" />'
    . (GOOGLE ? "\n" . '  <meta name="verify-v1" content="' . GOOGLE . '" />' : '')
    . (YANDEX ? "\n" . '  <meta name="yandex-verification" content="' . YANDEX . '" />' : '')
    . (WEBMONEY ? "\n" . '  <meta name="webmoney.attestation.label" content="' . WEBMONEY . '" />' : '')
    . "\n" . '  <link rel="alternate" href="feed.rss" type="application/rss+xml">
  <link rel="icon" href="favicon.ico" type="image/x-icon">
  <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">';
  }
}

/**
 * Класс ключевых влов
 */
class Keyword {

  var $version = 0.01;
  public $config = array('words' => 15, 'min' => 5, 'max' => 25);
  private $keywords = array();
  private $endings = array("ые", "ое", "ие", "ий", "ая", "ый", "ой", "ми", "ых", "ее", "ую", "их", "ым");
  private $exceptions = array("able", "about", "даже", "дал", "далее", "далеко"
  );

  /**
   *
   * @global Engine $engine
   */
  public function __construct() {
    global $engine;
    $this->keywords = preg_split("/[\s,]+/s", $engine->string->trim($engine->config['keywords']));
  }

  /**
   *
   * @global Engine $engine
   */
  function get() {
    global $engine;
    return (string) implode(", ", $this->keywords);
  }

  /**
   *
   * @global Engine $engine
   * @param <type> $key
   */
  function set($key) {
    global $engine;
    if (in_array($key, $this->keywords)):
      return false;
    else:
      $this->keywords[] = $key;
    endif;
  }

  /**
   *
   * @global Engine $engine
   */
  function clear() {
    global $engine;
    $this->keywords = array();
  }

  /**
   *
   * @global Engine $engine
   * @param string $text
   * @return mixed
   */
  function generate($text=null) {
    global $engine;
    $text = $engine->string->lower($text);
    // вырезаем теги, символы и лишние пробелы
    $text = $engine->string->clean($text);
    // создаем массив слов
    $words = preg_split("/[\s]+/s", $text);
    ...
    return $words;

  }

}

/**
 * Класс составления описания страницы
 */
class Description {

  var $version = 0.01;
  public $config = array('length' => 300);
  private $description = array();
  private $synonyms = array('searche' => 'replace');

  /**
   *
   * @global Engine $engine
   */
  public function __construct() {
    global $engine;
    $this->description = $engine->config['description'];
  }

  /**
   *
   * @global Engine $engine
   * @param <type> $key
   */
  function get() {
    global $engine;
    return $this->description;
  }

  /**
   *
   * @global Engine $engine
   * @param <type> $key
   */
  function set($string) {
    global $engine;
    $this->description .= $string;
  }

  /**
   *
   * @global Engine $engine
   */
  function clear() {
    global $engine;
    $this->description = null;
  }

  /**
   *
   * @global Engine $engine
   * @param string $text
   * @return mixed
   */
  function generate($text=null) {
    global $engine;
  }

}

/**
 * Класс заголовка страницы
 */
class Title {

  var $version = 0.01;
  public $config = array('length' => 300, 'separator' => ' - ');
  private $title = array();
  private $synonyms = array('searche' => 'replace');

  /**
   *
   * @global Engine $engine
   */
  public function __construct() {
    global $engine;
    $this->title[] = $engine->config['title'];
  }

  /**
   *
   * @global Engine $engine
   * @param <type> $key
   */
  function get() {
    global $engine;
    return (string) implode($this->config['separator'], $this->title);
  }

  /**
   *
   * @global Engine $engine
   * @param <type> $key
   */
  function set($string) {
    global $engine;
    $this->title[] = $string;
  }

  /**
   *
   * @global Engine $engine
   */
  function clear() {
    global $engine;
    $this->title = null;
  }

  /**
   *
   * @global Engine $engine
   * @param string $text
   * @return mixed
   */
  function generate($text=null) {
    global $engine;
  }

}

//
?>
 
не совсем вник в задачу, но кейворд можно сделать отдельным классом с методом __toString который позволит обращаться к кейворду как к обьекту так и к строке где нужно.
 
магические методы в этом случае ненужны, ими пользоватся умею...
увы то что хочется нельзя делать в пхп, да и нужна как то отпала...
нужно было расширение нужных свойст до методов со стандартным набором действий, и защищенным хранилищем внутри.
 
магические методы в этом случае ненужны, ими пользоватся умею...
увы то что хочется нельзя делать в пхп, да и нужна как то отпала...
нужно было расширение нужных свойст до методов со стандартным набором действий, и защищенным хранилищем внутри.

Пару замечаний по твоему коду:
1)
PHP:
return (string) implode(", ", $this->keywords);
зачем приводить к типу "string", если ф-я implode итак возвращает строку?

2) Есть такой паттерн проектирования как регистр(registry), который представляет из себя единое глобальное хранилище. На твоем месте я бы отказался от использования глобальных переменных в ф-ии в пользу регистра.

И еще по поводу твоей задачи: с выходом новой ветки php(5.4 или 6) появится поддержка traits(для непрошаренных это значит множественное наследование). Да и про импорт-оператор "use" ты наверняка не слышал...
 
у меня и так подобие но только без __clone
у меня однократная инициализация, вот иногда нужно перезагружать класс с другим расширением но пока не придумал как,
поэтому у меня большая зависимость между классами, 50% мелких классов самодостаточна но более крпные прямолинейно зависят от мелких...
хранилищем у меня выступает корневой класс Engine в который загружаются новый классы при обращении к несуществющему свойству, методу и тп...

про (string) да приведение, поидее нужно делать именно так но у нас мало кто так делает, да и там не полный набор показан, часть просто вырезана.
 
у меня и так подобие но только без __clone
у меня однократная инициализация, вот иногда нужно перезагружать класс с другим расширением но пока не придумал как,
поэтому у меня большая зависимость между классами, 50% мелких классов самодостаточна но более крпные прямолинейно зависят от мелких...
хранилищем у меня выступает корневой класс Engine в который загружаются новый классы при обращении к несуществющему свойству, методу и тп...

про (string) да приведение, поидее нужно делать именно так но у нас мало кто так делает, да и там не полный набор показан, часть просто вырезана.
так почему надо делать приведение к типу "string", если ф-я implode итак возвращает строку?
 
да и там не полный набор показан, часть просто вырезана.
у меня часть кода вырезана... там вызов еще некоторых ключей)
(int)(string) по большей части, привычка писать...
просто где то читал что типа так нужно... да и сам не читаю что они возвращают, а то есть и mixed) а так поменяю чего и все будет все равно норм)
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху