2013-07-26 1 views
1

В CodeIgniter я хочу подготовить значение, возвращаемое из формы, так что если оно равно 0, оно будет фактически вставлено как NULL.Подтверждение значения «0» в NULL

Я создал функцию вне моего класса контроллера:

function prep_zero_to_null($int) 
{ 
    if ($int == 0) 
    { 
     return NULL; 
    } 
    else 
    { 
     return $int; 
    } 
} 

И в проверке формы, я:

$this->form_validation->set_rules('category_id', 'Category', 
            'required|integer|prep_zero_to_null'); 

Однако CI все еще пытается вставить нули в '0' в базе данных , что нарушает одно из ограничений моего внешнего ключа.

Интересно, если я заменю NULL, скажем, 25 в функции prep_zero_to_null, CI действительно распознает его и вставить 25 вместо '0'. Поэтому моя функция prepping действительно вызвана, но CI не позволит NULL в результате этого и вместо этого преобразует ее в '0'.

Как я могу достичь того, чего хочу?

Edit: Для тех, кому интересно, то category_id поле действительно позволяет нуль:

`category_id` int(10) unsigned DEFAULT NULL 

И точная ошибка:

INSERT INTO `articles` (`category_id`, `order`, `title`, `text`) 
VALUES ('0', '0', 'test', 'test') 
     ^
     Should be NULL 

Cannot add or update a child row: a foreign key constraint fails 
(`db`.`articles`, CONSTRAINT `articles_ibfk_1` FOREIGN KEY 
(`category_id`) REFERENCES `categories` (`id`) 
ON DELETE SET NULL ON UPDATE CASCADE) 
+1

Я уверен, что вы должны возвращать строку null вместо константы: 'return 'NULL';' Но опять же, если это указано в запросе, вы не получите желаемого эффекта. – nickb

+1

Ну, я думаю, что соответствующий столбец базы данных не допускает значений NULL и имеет значение «0», поскольку это значение по умолчанию. –

+0

Столбец таблицы разрешает NULL? –

ответ

1

Просто глядя на это быстро, я думаю, что проблема СВОЙ $ int == 0. Является ли $ int фактическим целым числом типа 0 или является ли это строкой? В этом случае правильная проверка будет $ int == '0'.

+0

Нет, потому что я делаю свободное сравнение (' == 'вместо' === '). Согласно документу PHP, '0 ==" 0 "'. Источник: http://php.net/manual/en/types.comparisons.php – Lazlo

+0

Кроме того, даже если я заменил весь объект функции просто «return NULL», я получаю ту же проблему. – Lazlo

+0

Вы правы: D – virtuexru

0

Если вы хотите вставить нуль в базу данных, вам нужно вернуть строку со значением «null».

function prep_zero_to_null($int) { 
    return ($int == 0) ? 'NULL' : $int; 
} 
+0

Это не работает. Он попытается вставить '' NULL'' (а не 'NULL' ключевое слово) в запрос, который отличается в синтаксисе MySQL. – Lazlo

+0

О, okey. Я не использую с воспламенителем кода. Но вы не должны добавлять дополнительные кавычки в свой запрос. Действительно ли Code Igniter делает это автоматически? – Anders

+0

Да, как и следовало ожидать, с учетом строки он может интерпретировать только значение как таковое и соответствующим образом ссылаться на запросы базы данных. – Lazlo

0

Вы пытались просто отключить переменную. Это немного уродливо, но тогда оно должно возвращать значение NULL.

Tested here.

+0

Это нечто более уродливое, вы возвращаете неназначенную переменную (к которой стандартная установка PHP будет устно жаловаться на уведомление). Более того, проблема заключается не в том, что моя функция фактически не возвращает 'NULL' (она делает), но что CI игнорирует это и все еще вставляет' '0''. – Lazlo

+2

Да, это было просто доказательством концепции, потому что я не был уверен, в чем была проблема. Похоже, что CodeIgniter просто не нравится значение NULL при проверке и только разрешает его непосредственно устанавливать в базу данных. Странно, вам может быть лучше подавать ошибку в свой трекер. – Aeveus

0

попробовать

if (!$int) 
    $this->db->set('category_id', NULL); 
+0

Я еще не на уровне базы данных (модели), но на уровне проверки (контроллера). Я мог бы попробовать это, но это очень уродливый, несовместимый с MVC хак. – Lazlo

+0

haha ​​все работает ... Вы еще пытались отключить переменную? если он пуст, тогда это должно выдавать допустимый результат. '$ int = empty ($ int)? NULL: $ int; ' – XaxD

+0

Это то, что моя функция делает уже, в другом синтаксисе (я попытался и получил тот же результат). – Lazlo

0

Я представил вопрос на багтрекер GitHub для CodeIgniter, так как это, кажется, ошибка. https://github.com/EllisLab/CodeIgniter/issues/2563

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

$category_id = prep_zero_to_null($this->input->post('category_id')); 

$data = array 
(
    'category_id' => $category_id, 
    'order' => $this->input->post('order'), 
    'title' => $this->input->post('title'), 
    'text' => $this->input->post('text') 
); 

Edit: По-видимому, это правильный подход, так как там должен быть только строки на уровне проверки/контроллера.

1

Функции проверки подлинности Codeigniter не устанавливают значение поля на основе того, что вы возвращаете, ваша функция проверки должна либо возвращать TRUE, либо FALSE, чтобы указать, что что-то действительно или нет.

Если вы после изменения значения чего-то, вам нужно принять переменную по ссылке и изменить ее в функции, тогда вы можете вернуть TRUE, чтобы она прошла проверку.

Лучшим решением было бы сделать проверку перед вставкой данных в базу данных &, не полагаясь на библиотеку валидации для выполнения этой грязной работы.

+0

Я бы подумал, что второе предложение вашего ответа является ключом к этой проблеме, но действительные функции prepping, такие как 'trim' или' md5', не работают, ссылаясь на первый аргумент, а наоборот, возвращая новое значение. И, как говорит док, «любая собственная функция PHP, которая принимает один параметр, может использоваться, как правило, как htmlspecialchars, trim, MD5 и т. Д.». – Lazlo

+0

Да, я думаю, вы правы на этом, не могли бы вы попробовать так? if ((int) $ int == 0) return NULL; – ahmad

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