У меня есть MVC-приложение среднего размера. Варианты использования для приложения таковы, что мне требуется немного больше контроля над SQL, используемым для взаимодействия с моей базой данных (среди прочего, данные сильно нормализованы, и мы используем МНОГО соединений). Итак, я вырастил свой собственный дизайн для моделей, а не использовал Doctrine, Eloquent или что-то еще. Я недавно обнаружил, что мой дизайн называется Таблица данных Шлюз шаблон. В любом случае, это выглядит так (немного упрощено для ясности):
У нас есть абстрактный класс, который расширяет все мои TableGateways. Он знает, как разговаривать с PDO и выполнять SQL-операции, но не о какой-либо конкретной таблице:
abstract class TableGateway {
protected $db = null;
public $tableName = '';
public $outputClass = null;
function __contruct(\PDO $pdo) {
$this->db = $pdo;
}
/**
* $return \StdClass[]
*/
function all() {
$result = $this->query(sprintf('SELECT * FROM %s',$this->tableName));
return $result;
}
/**
* @param $query
* @param array $params
* @return \StdClass[]
*/
public function query($query, $params = array()) {
$stmt = $this->db->prepare($query);
if($this->outputClass) {
$stmt->setFetchMode(PDO::FETCH_CLASS, $this->outputClass);
} else {
$stmt->setFetchMode(PDO::FETCH_OBJ);
}
$success = $stmt->execute($params);
return $stmt->fetchAll();
}
}
Затем у каждой таблицы есть класс шлюза, который расширяет родительский класс и применяет специфичные для таблицы вещи. Здесь будет много функций, которые вызывают $this->query()
привнося свои знания о структуре таблицы для создания полезного запроса, но есть также некоторые основные функции, такие как PostsGateway::all()
которые одинаковы для каждой таблицы, поэтому они живут в родительском классе.
class PostsGateway extends TableGateway {
public $tableName = 'posts';
public $outputClass = 'Post';
}
Каждый результат запроса загружается в объект. По умолчанию это просто объекты StdClass, но вы можете указать альтернативный $this->outputClass
чтобы они выводились в этом другом классе, как этот:
class Post {
/** @var int $id */
/** @var string $content */
}
Все это работает очень хорошо для меня. Тем не менее, моя IDE не может идти в ногу. Ты и я это знаем PostsGateway::all()
собирается вернуть массив Post
объекты, но IDE думает, что это обычный массив. Это означает, что я не автозаполняю подсказки для свойств Post
объекты.
Кто-нибудь знает какие-нибудь умные способы решить эту проблему, чтобы IDE узнала об этом изменении?
Я думал о сценарии для автоматического создания блоков документов для PostsGateway
, но я немного опасаюсь кода gen в целом, и особенно кода gen в классе, который я собираюсь периодически модифицировать. Сценарий должен будет периодически обновлять блоки документов, основываясь на изменениях в TableGateway
и ничего не испортил PostsGateway
,
Есть ли другие интересные способы обойти это? Или вы можете порекомендовать несколько хороших библиотек для генерации этих блоков кода?
Задача ещё не решена.
Других решений пока нет …