Несколько вопросов от новичка

Здравствуйте. В работе с Yii я пока новичёк (всего 3 дня использую), поэтому решил попросить помощи на форуме. Интересуют 3 вопроса.

  1. Как сделать так что бы Yii не выбрасывал исключения при использовании необъявленной переменной или ячейки массива (аналог обычных Notice`ов в чистом php)?

  2. Как использовать flash-сообщения? Если я правильно понял, почитав форум, то нужно записать flash-сообщение и перенести пользователя на нужную страницу, на которой считать и показать ранее записанное flash-сообщение.

Просто на некоторых фреймворках эти же flash-сообщения показываются автоматически на отдельной странице типа "Спасибо что вошли, сейчас вас перенесёт на страницу…".

В документации я не нашёл ничего именно по использованию flash-сообщений. Искал даже гуглом (site:yiiframework.com setFlash - и подобные запросы) но напарывался либо на 2 темы в форуме о проблемах с setFlash (именно из их содержимого мне кажется что я прав), либо на api-документацию.

  1. Как при валидации проверять не совпадение с правилами, а несовпадение? Например я при помощи exist-правила хочу проверить - есть ли введённый логин в базе. И если есть то в массив ошибок поместить соответствующее сообщение.
  1. define('YII_ENABLE_ERROR_HANDLER', false); во входной скрипт

  2. http://www.yiiframew…oc/cookbook/21/

  3. exist-валидатор как раз делает, то что требуется

Спасибо за помощь! Только я не совсем понял на счёт exist.

Вот правило которым я хочу проверить - есть ли пользовать в базе

array('login','exist','attributeName'=>'id','on'=>'register','message'=>'Login in base!'),

но при регистрации правило выдаёт ошибку только тогда когда введёного логина в базе нет.  А мне нужно наоборот.

Неправильно сначала понял вопрос, нужна проверка на уникальность, делается так array('login','unique','attributeName'=>'id','on'=>'register','message'=>'Login in base!')

почитай внимательно http://www.yiiframew…alidation-rules

Спасибо! То что нужно.

Скажите пожалуйста, какого формата должен быть языковой файл сообщений? Везде написано "Файл должен возвращать массив сообщений…". Но ведь сам файл ничего возвращать не может. Значит там должна быть какая-то функция или класс который возвратит это. Если не трудно, дайте код такого файла с 1 переведённой фразой.

Quote

Скажите пожалуйста, какого формата должен быть языковой файл сообщений? Везде написано "Файл должен возвращать массив сообщений...". Но ведь сам файл ничего возвращать не может. Значит там должна быть какая-то функция или класс который возвратит это. Если не трудно, дайте код такого файла с 1 переведённой фразой.


<?php


return array(


    'Привет' => 'Hello',


);


?>


Спасибо :o первый раз вижу такое. Раньше я думал что это невозможно.

Quote

Спасибо :o первый раз вижу такое. Раньше я думал что это невозможно.

привыкайте. в Yii такой подход практически везде используется :) смотрите к примеру config/main.php :)

Quote

Неправильно сначала понял вопрос, нужна проверка на уникальность, делается так array('login','unique','attributeName'=>'id','on'=>'register','message'=>'Login in base!')

почитай внимательно http://www.yiiframew…alidation-rules

ИМХО такое правило валидации вероятней всего правильней вынести на уровень базы данных ?? и в связи с этим вопрос как получить красивое сообщение об ошибке а не exception в таком случае … и оправдан ли такой подход ?

если в друг не понятно то я поясню - к примеру проверку уникальности имени (пользователя или еще чего) можно осуществить средствами базы данных, указав что это поле является либо UNIQUE либо PRIMARY_KEY. В таком случае при вставке данных и не использовании правила валидации

array('login','unique')

возникает ошибка и мы получим

CDbException

Description

CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'qwe' for key 2

Это я попытался создать второго пользователя с одинаковым именем

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

и правильно ли, как Вам кажется, делать еще один дополнительный запрос на выяснение а есть ли у нас уже такой пользователь или нет …

Спасибо.

зачем усложнять себе работу, когда фреймворк делается для обратного?

CUniqueValidator делает  за программиста "дополнительный запрос на выяснение а есть ли у нас уже такой пользователь или нет" и затем в удобном настраиваемом виде сообщает об ошибке, если она есть

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

Quote

зачем усложнять себе работу, когда фреймворк делается для обратного?

CUniqueValidator делает  за программиста "дополнительный запрос на выяснение а есть ли у нас уже такой пользователь или нет" и затем в удобном настраиваемом виде сообщает об ошибке, если она есть

Потому как в высоконагруженных системах это один лишний запрос может быть способом оптимизировать систему.

Опять таки руководствуясь моей логикой, спрашивается зачем тогда использовать базу только как storage ? ведь она умеет немного больше :slight_smile:

Я могу ошибаться - но мне кажется что если нужно что б поле было уникальным об этом должна заботится база данных, сохраняя тем самым целостность данных.

Quote

Quote

зачем усложнять себе работу, когда фреймворк делается для обратного?

CUniqueValidator делает  за программиста "дополнительный запрос на выяснение а есть ли у нас уже такой пользователь или нет" и затем в удобном настраиваемом виде сообщает об ошибке, если она есть

Потому как в высоконагруженных системах это один лишний запрос может быть способом оптимизировать систему.

Опять таки руководствуясь моей логикой, спрашивается зачем тогда использовать базу только как storage ? ведь она умеет немного больше :slight_smile:

Я могу ошибаться - но мне кажется что если нужно что б поле было уникальным об этом должна заботится база данных, сохраняя тем самым целостность данных.

Такой подход понятен и применим, только какой либо-существенной оптимизации в данном случае не удастся достичь, по причине того, что такая проверка, в основном, проводится при регистрации, а регистрация дело не такое уж частое, чтобы отнимать много ресурсов, но назначить индекс типа UNIQUE будет полезно, как для общей производительности, так и дл целостности.

"и правильно ли, как Вам кажется, делать еще один дополнительный запрос на выяснение а есть ли у нас уже такой пользователь или нет …"

Это и есть единственно правильный путь. Неправильно пытаться запихать запись в базу и на основе низкоуровневого исключения БД о вопросе целостности принимать решение о валидности того или иного поля. Есть ещё много причин почему это идеологически неправильно и профессионалы так никогда не сделают.

P.S. Никакой оптимизацией тут и в помине не пахнет. Что в том, что в ином случае делается запрос. В случае валидатора SELECT, во втором INSERT. Причем во втором случае операция будет дороже.

Quote

Неправильно пытаться запихать запись в базу и на основе низкоуровневого исключения БД о вопросе целостности принимать решение о валидности того или иного поля.

Согласен. Но! Оставлять поля без признака UNIQUE нельзя. Вот вы знаете, как обидно смотреть на “программистов”, которые на бумаге нарисовали свою структуру “БД” с линиями (или даже стрелочками) между таблицами (они видели, что так в Access делают или им показывали в книжках их “преподаватели”), а сами не понимают зачем эти линии-стрелочки нужны и как это потом работает в реальных СУБД. Я сейчас говорил о внешних ключах и связности таблиц.

Я за принцип совмещения - и в логике кода и в логике БД должны быть проверки на уникальность, на внешние ключи и на все, что нужно. Так мы будем застрахованы от малограмотных или неопытных программистов, которые могут быть допущены к разработке системы, в которой участвуют очень много людей.

Полностью согласен. Защита на всех слоях необходима. В некоторых других случаях помимо валидации на уровне модели и защиты целостности UNIQUE индексами на уровне БД по возможности стоит добавлять валидацию на клиенте при помощи допустим javascript, для избежания запроса к серверу в высоконагруженных системах.

а что насчет внешних ключей ?

дело в том что попытка удалить то что нельзя удалить вызовет исключение и ошибку уровня базы данных… Есть ли в Yii метод позволяющий проверить может ли данная запись быть удалена ? в смысле не поптка ли это нарушить целостностьб базы данных … вот о чеи я.

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

  1. от этой записи может зависить ооочень много других записей и таблиц (да и не понятно как узнать об этом). Просто скажем у меня порядка двух сотен таблиц и в большинстве из них данные имеют связь с этой записью (которую мы хотим удалить), не понятно как это определить да и зачем это делать если это делает БД ?

  2. хочется получить некую "красивую" ошибку, точнее сообщение о ней, а не эксепшн…

Булу рад любому совету.

Спасибо.

и еще в догонку к предыдущему вопросу…

а чем логически отличается

BELONGS_TO:

и

HAS_MANY:

???

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

я всегда думал что есть только три типа отношейни

а тут четыре  ???

Читайте тут - http://www.yiiframew…ru/database.arr

А вообще BELONGS_TO это тоже самое что HAS_MANY только верх ногами. т.е. например если б вы делали что одному юзеру принадлежат много комментариев - то это HAS_MANY. А вот если вы скажите что многим комментариями принадлежит один пользователь - тогда это BELONGS_TO.