Недавно передо мной встала задача, для решения которой удобно использовать PHP фреймворк. Изучив доступную информацию, описание, возможности,опрос на хабре (в котором, кстати, сумма опрошенных равна не 100%, а 143% (?)) был выбран Yii. Меня этот фреймворк устроил наличием необходимых фич, таких как авторизация и капча. На официальном сайте написано:
Yii — это высокоэффективный, основанный на компонентной структуре PHP-фреймворк для быстрой разработки крупных веб-приложений. Он позволяет максимально применить концепцию повторного использования кода и может существенно ускорить процесс веб-разработки.
Однако моё знакомство с Yii, которое началось с красивых формочек для генерации кода, быстро перешло к копанию в исходниках.
После установки всё шло гладко. По инструкции попробовал создать тестовый сайт, сгенерировал модель и CRUD с помощью Gii для таблицы пользователей. Пощёлкал – всё работает.
Настало время выполнить всё то же самое, но для MySQL. Как раньше, захожу в генератор модели, ввожу имя таблички и вижу: “Table 'user' does not exist.”. Странно. Наверно что-то не так настроил. Около часа сверялся с мануалами и примерами — всё как у всех, но таблички не видно. Попробовал подключиться к БД в коде:
$connection=Yii::app()->db;
$sql="SELECT * FROM user";
$dataReader=$connection->createCommand($sql)->query();
while(($row=$dataReader->read())!==false)
{
echo var_dump($row);
}
Всё работало. Хотя Gii таблицу не видел. В интернете ничего кроме как проверить в очередной раз конфигурацию сайта и наличие таблички в MySQL не предлагали. Эти два пункта я уже неоднократно выполнял и поэтому решил посмотреть, как Gii пытается найти табличку в исходниках.
Отправная точка обнаружилась случайно. Когда я тестировал с различными строками подключения к БД – в отладочной информации отобразилось место, в котором производилось подключение к БД. По соседству находилась функция, которая проверяла имя таблички и в случае её отсутствия выдавала мою ошибку. Потратив несколько часов на вставку var_dump-ов и отслеживания путей выполнения, я произвёл изучение следующих мест:
Имя файла | Функция |
/yii/framework/gii/generators/model/ModelCode.php | validateTableName |
/yii/framework/gii/generators/model/ModelCode.php | getTableSchema |
/yii/framework/db/schema/CDbSchema.php | getTable |
/yii/framework/db/schema/mysql/CMysqlSchema.php | loadTable |
/yii/framework/db/schema/mysql/CMysqlSchema.php | findColumns |
В итоге в функции findColumns был обнаружен код, который привел меня к решению проблемы:
protected function findColumns($table)
{
$sql='SHOW FULL COLUMNS FROM '.$table->rawName;
try
{
$columns=$this->getDbConnection()->createCommand($sql)->queryAll();
}
catch(Exception $e)
{
return false; // !
}
// ...
}
Да-да! Никакой обработки возможных исключений, никакой информации о них, просто return false (который, кстати, в вызывающей функции превращался в null). Добавив перед возвратом false очередной var_dump, удалось обнаружить, что MySQL не может создать временный файл: Can't create/write to file /var/tmp/mysql. (Errcode: 2). С этой информацией уже можно было действовать дальше. Например, мне помогло это.
Кстати, забыл упомянуть, что я новичок в PHP. Не знаю, как бы проблему решили более опытные коллеги. Буду рад услышать советы. Для себя планирую в ближайшее время в исходниках Yii добавить проверку режима отладки и вывод информации о возникающих исключениях. Пошёл генерировать модели для своих табличек =)
Автор: PetrovSerega