[Решено]Вопрос спецам.

Главные вкладки

Аватар пользователя ihappy ihappy 26 января 2010 в 17:02

Всем доброго времени суток.
Столкнулся с такой проблемой. Уже решил, но вопрос остался, а почему так себя ведет.
Я не великий спец, многого не знаю. Вот интересно оченб.
В общем проблема была следующая.
Есть текстовое поле и кнопка.
При нажатии кнопки в БД записывается значение текстового поля. Все просто и элементарно.
Только у меня писалось 0 или 1. Как FALSE и TRUE в общемто. Помучался с пол часа, я переписал вся с нуля. и все заработало.
Разница не большая. Смотрите сами.

Вот при этом коде, 0 или 1.

<?phpfunction comparison_add_form($form_state) {

$form['comparison'] = array( 
    '#type'  => 'fieldset', 
    '#title' => t('Stores') 
  ); 
   
  $form['comparison']['nid'] = array( 
    '#type'  => 'value', 
    '#value' => $param1->nid 
  ); 
   
  $form['comparison']['store'] = array( 
    '#type'          => 'textarea', 
    '#title'         => t('Название магазина'), 
    '#description'      =>  t('Add store to BD') 
  ); 
   
  $form['comparison']['submit'] = array( 
    '#type'  => 'submit', 
    '#value' => t('Добавить') 
  ); 
 
 $form['check_comparison'] = array( 
    '#type'  => 'fieldset', 
    '#title' => t('Stores') 
  ); 
  
  
 $form['check_comparison']['store'] = array( 
    '#type'          => 'checkbox', 
    '#title'         => t('Название магазина'), 
    '#default_value' => '', 
    '#description'      =>  t('Add store to BD') 
  );
  return $form; 
}

function comparison_add_form_submit($form, &$form_state) {
global $user;

$store = ($form_state['values']['store']);
$query = ("INSERT INTO {stores} (uid, stores) VALUES ('', '$store' )");
echo $store;
$result = db_query($query);

    if ($result) {
        drupal_set_message (t('Shop added to database'));
    }
    else {
        drupal_set_message (t('shop is not added to the database')); 
    }

}?>

А при этом, все как и должно быть.

<?php
function comparison_add_form($form_state) {

$form['store'] = array( 
    
'#type'  => 'fieldset'
    
'#title' => t('Stores'
  ); 
   
  
$form['store']['nid'] = array( 
    
'#type'  => 'value'
    
'#value' => $param1->nid 
  
); 
   
  
$form['store']['name'] = array( 
    
'#type'          => 'textarea'
    
'#title'         => t('Название магазина'), 
    
'#description'      =>  t('Add store to BD'
  ); 
   
  
$form['store']['submit'] = array( 
    
'#type'  => 'submit'
    
'#value' => t('Добавить'
  ); 
 
 
$form['check_comparison'] = array( 
    
'#type'  => 'fieldset'
    
'#title' => t('Stores'
  ); 
  
  
 
$form['check_comparison']['store'] = array( 
    
'#type'          => 'checkbox'
    
'#title'         => t('Название магазина'), 
    
'#default_value' => ''
    
'#description'      =>  t('Add store to BD'
  );
  return 
$form
}

function 

comparison_add_form_submit($form, &$form_state) {
global 
$user;

$store = ($form_state['values']['name']);
$query = ("INSERT INTO {stores} (uid, stores) VALUES ('', '$store' )");
echo 
$store;
$result db_query($query);

    if (

$result) {
        
drupal_set_message (t('Shop added to database'));
    }
    else {
        
drupal_set_message (t('shop is not added to the database')); 
    }

}

?>

не пойму в чем прикол? или у меня ету лыж или асфальт не скользкий? ))
Подскажите, чтобы в следующий раз время не тратил. Спасибо.

Комментарии

Аватар пользователя graker graker 26 января 2010 в 17:55

1. Вероятнее всего, возникал конфликт имен ('store') для текстового поля и чекбокса. Чтобы все заработало в первом варианте, надо поле fieldset снабдить элементом '#tree' => TRUE, который указывает принудительно сохранять древовидную структуру элементов филдсета в $form_state['values'].
Вот так:

$form['comparison'] = array(
  '#type'  => 'fieldset',
  '#title' => t('Stores'),
  '#tree' => TRUE,
);
//...
$form['check_comparison'] = array(
  '#type'  => 'fieldset',
  '#title' => t('Stores'),
  '#tree' => TRUE,
);

Тогда в $form_state['values'] значения текста и чекбокса будут гарантированно в разных под-массивах ($form_state['values']['comparison']['store'] и $form_state['values']['check_comparision']['store'] соответственно).

2. Лыжи могут вас увезти в очень нехорошее место, если будете содержимое формы вставлять прямо в текст SQL-запроса.

Аватар пользователя glu2006 glu2006 26 января 2010 в 17:34

А концовку скрипта я бы переписал так:

<?php
function comparison_add_form_submit($form, &$form_state) {
global 
$user;

$store = ($form_state['values']['name']);
echo 
$store;
$result db_query("INSERT INTO {stores} (uid, stores) VALUES ('%d', '%s')"$user->uid$store);

    if (

$result) {
        
drupal_set_message (t('Shop added to database'));
    }
    else {
        
drupal_set_message (t('shop is not added to the database')); 
    }

}

?>
Аватар пользователя ihappy ihappy 26 января 2010 в 18:44

"graker" wrote:
1. Вероятнее всего, возникал конфликт имен ('store') для текстового поля и чекбокса. Чтобы все заработало в первом варианте, надо поле fieldset снабдить элементом '#tree' => TRUE, который указывает принудительно сохранять древовидную структуру элементов филдсета в $form_state['values'].
Вот так:

$form['comparison'] = array(
'#type' => 'fieldset',
'#title' => t('Stores'),
'#tree' => TRUE,
);
//...
$form['check_comparison'] = array(
'#type' => 'fieldset',
'#title' => t('Stores'),
'#tree' => TRUE,
);

Тогда в $form_state['values'] значения текста и чекбокса будут гарантированно в разных под-массивах ($form_state['values']['comparison']['store'] и $form_state['values']['check_comparision']['store'] соответственно).


Спасибо, учту. Сейчас проверю, так ли это.

upd: проверил. Теперь в БД вообще пустое поле заносится. вопрос таки не решен.

"graker" wrote:
2. Лыжи могут вас увезти в очень нехорошее место, если будете содержимое формы вставлять прямо в текст SQL-запроса.

"glu2006" wrote:
А концовку скрипта я бы переписал так:

Спасибо за подсказку, [стыдно] это не учел [/стыдно]

Аватар пользователя graker graker 26 января 2010 в 22:11

metakon wrote:
upd: проверил. Теперь в БД вообще пустое поле заносится. вопрос таки не решен.

Ну так выведите $form_state['values'] и посмотрите, чего там где, делов-то. А вообще почитайте Form API Reference, там все это написано.

Аватар пользователя ihappy ihappy 27 января 2010 в 21:15

"graker" wrote:
Ну так выведите $form_state['values'] и посмотрите, чего там где, делов-то. А вообще почитайте Form API Reference, там все это написано.

Да как API по формам уже издьездил. Сделано все правильно.
да и проблема давно решена.
мне просто интересно, почему?

Аватар пользователя graker graker 27 января 2010 в 21:53

Я сейчас уже ей богу не помню, где это было написано, но в общем фишка в том, что если #tree не установлен, то значения всех элементов формы будут по возможности записаны в одномерный массив $form_state['values']. При этом, естественно, не может быть двух одинаковых имен элементов - как их резолвить? Поэтому, полагаю, вам "не повезло": в одномерный массив попал чекбокс, а текстовое поле сохранило структуру филдсета и оказалось в ['values']['comparision']. Именно ввиду подобных конфликтов и во избежание путаницы имеет смысл для филдсетов сохранять древовидную структуру.

Аватар пользователя ihappy ihappy 28 января 2010 в 2:47

Запомним на будущие и не будем допускать таких ошибок.
Спасибо.

PS проверять не буду, на то и времени нету, и надобности нету. вопрос думаю решен.