Я не очень уверен, верен ли мой вопрос о заголовке, однако я столкнулся с серьезной ошибкой нескольких циклов в foreach, несмотря на то, что в массиве есть только один элемент. Я вставляю сюда свой код;
Отображать (Контроллер)
$table_data = array(
'table_data' => $this->display_model->get_table_data($table_name),
'edit_table_data'=>$this->display_model->get_table_data($table_name,$row_id)
);
$form_name='edit_'.$table_name;
$this->load->view('header');
$this->load->view($form_name,$table_data);
$this->load->view('footer');
Вы можете видеть, что tabe_data и edit_table_data вызывают одну и ту же функцию с другим параметром. Здесь я сомневаюсь в планировании времени между этими двумя вызовами функций (что, честно говоря, я ошибаюсь, потому что codeigniter управляет вызовами функций)
Display_model (Модель)
public function get_table_data($table_name,$row_id=null)
{
$return = "";
if ($row_id != null)
{
switch ($table_name) {
case 'user':
//$return = $this->db->where($table_name."_id",$row_id)->get($table_name)->result();
$return = $this->db->select($table_name.'.*,country.country_name')
->join('country','country.country_id=user.user_country_id','left')
->where($table_name.'_id',$row_id)
->get($table_name)->result();
break;
case 'user_document':
//$return = $this->db->where($table_name."_id",$row_id)->get($table_name)->result();
$return = $this->db->select($table_name.'.*,document.document_name')
->join('document','document.document_id=use_document.document_id','left')
->where($table_name.'_id',$row_id)
->get($table_name)->result();
break;
default:
$return = $this->db->where($table_name."_id",$row_id)->get($table_name)->result();
break;
}
if ($return != null)
{
return $return;
}
else
{
return "no_data";
}
}
Вот мое мнение, где я получаю сообщение об ошибке
<?php foreach ($edit_table_data as $etd_row) {?>
<form method = "post" class = "form-horizontal" action = "<?php echo site_url('admin/edit_row/user_type/'.$etd_row->user_type_id)?>">
<div class = "form-group">
<label class = "col-sm-4 control-label">User Type Name</label>
<div class = "col-sm-8"><input type = "text" class = "form-control" name = "user_type_name" value = "<?php echo $etd_row->user_type_name?>"></div>
</div>
<div class = "hr-line-dashed"></div>
<div class = "form-group">
<div class = "col-sm-2 col-sm-offset-2">
<button class = "btn btn-primary" type = "submit">Edit changes</button>
</div>
</div>
</form>
<?php } ?>
в строке цикла foreach я получил ошибку
заранее благодарю за ваши комментарии
Ошибка
A PHP Error was encountered
Severity: Warning
Message: Invalid argument supplied for foreach()
Filename: views/edit_user_type.php
Line Number: 18
Backtrace:
File: C:\wamp\www\gmf\application\views\edit_user_type.php
Line: 18
Function: _error_handler
File: C:\wamp\www\gmf\application\controllers\Display.php
Line: 170
Function: view
File: C:\wamp\www\gmf\index.php
Line: 315
Function: require_once
проверьте пусто, как это в вашем представлении if (! empty($edit_table_data)){ foreach($edit_table_data as $etd_row){}}
На самом деле $ edit_table_data - это массив, и он не равен нулю, проверял это в модели и просмотре, в обоих местах






Вы получите эту ошибку, если $edit_table_data не является массивом - в данном случае, вероятно, строкой.
Мои знания CI немного устарели, но я думаю, что что-то в этом роде может вам помочь:
$query = $this->db->select($table_name.'.*,country.country_name')
->join('country','country.country_id=user.user_country_id','left')
->where($table_name.'_id',$row_id)
->get($table_name);
if ($query->num_rows() === 0){
return []; // Make sure we're always returning an array.
// I'd rather handle this stuff in the view...
// Probably some kind of message that shows:
// that there are not results when $edit_table_data is not an array, otherwise loop.
}
return $query->result();
Или вы можете сделать что-то в этом роде:
<?php
if (!is_array($edit_table_data)) {
echo 'No results here.';
} else {
foreach ($edit_table_data as $etd_row) { ?>
<form method = "post" class = "form-horizontal"
action = "<?php echo site_url('admin/edit_row/user_type/' . $etd_row->user_type_id) ?>">
<div class = "form-group">
<label class = "col-sm-4 control-label">User Type Name</label>
<div class = "col-sm-8"><input type = "text" class = "form-control" name = "user_type_name"
value = "<?php echo $etd_row->user_type_name ?>"></div>
</div>
<div class = "hr-line-dashed"></div>
<div class = "form-group">
<div class = "col-sm-2 col-sm-offset-2">
<button class = "btn btn-primary" type = "submit">Edit changes</button>
</div>
</div>
</form>
<?php
}
}
?>
Я обновил свой вопрос и добавил ошибку, не могли бы вы проверить. Проблема в том, что массив не пуст, и это массив, потому что редактирование для заполняется, что означает, что цикл foreach выполняется. Однако он работает без остановки.
Кажется, нет причин вызывать get_table_data дважды, один раз с $row_id и один раз без него, потому что вы никогда не используете $table_data['$table_data'] в представлении. В интересах получения чего-то, что работает, этот первый звонок следует исключить. Доработанный контроллер выглядит так.
$table_data['edit_table_data'] = $this->display_model->get_table_data($table_name,$row_id) ;
$form_name='edit_'.$table_name;
$this->load->view('header');
$this->load->view($form_name,$table_data);
$this->load->view('footer');
В коде модели в вопросе отсутствует фигурная скобка }, закрывающая это утверждение.
if ($row_id != null)
{
Поэтому немного сложно сказать, что именно вы хотите, если $row_id не предоставляется. Без дополнительной информации я считаю, что get_table_data не должен давать второму аргументу значение по умолчанию. Другими словами, функция должна быть определена без значения по умолчанию для `$ row_id - вот так.
public function get_table_data($table_name, $row_id)
Без значения по умолчанию для `$ row_id возникает фатальная ошибка, если значение не указано. Таким образом, контроллеру необходимо убедиться, что указано значение. Точно так же контроллер всегда должен проверять, подходит ли возврат модели, или модель всегда должна возвращать что-то, что может использовать представление.
get_table_data() содержит много повторяющегося кода - where($table_name.'_id', $row_id) и get($table_name)->result() появляются по три раза каждый. Изменяя логику, можно исключить повторяющиеся строки, чтобы сделать функцию более лаконичной. Рассмотрим эту версию.
public function get_table_data($table_name, $row_id)
{
if ($table_name === 'user')
{
$this->db
->select($table_name.'.*, country.country_name')
->join('country', 'country.country_id = user.user_country_id', 'left');
}
elseif ($table_name === 'user_document')
{
$this->db
->select($table_name.'.* ,document.document_name')
->join('document', 'document.document_id = use_document.document_id', 'left');
}
return $this->db
->where($table_name."_id", $row_id)
->get($table_name)
->row();
}
Вышеупомянутое возвращает данные из любого $table_name, где $table_name."_id" == $row_id. Конкретные предложения «select» и «join» добавляются в случае таблиц user или user_document.
Поскольку вам кажется, что вас интересует только одна строка, вам следует называть row() вместо result().
Важно знать, что db->row() вернет NULL, если записи не найдены. Этот факт можно использовать для проверки возврата модели и соответствующей реакции. В этом случае мы делаем проверку в представлении. Потому что там всего одна строка. foreach не требуется.
<?php if (isset($edit_table_data)) { ?>
<form method = "post" class = "form-horizontal" action = "<?php echo site_url('admin/edit_row/user_type/'.$edit_table_data->user_type_id) ?>">
<div class = "form-group">
<label class = "col-sm-4 control-label">User Type Name</label>
<div class = "col-sm-8"><input type = "text" class = "form-control" name = "user_type_name" value = "<?php echo $edit_table_data->user_type_name ?>"></div>
</div>
<div class = "hr-line-dashed"></div>
<div class = "form-group">
<div class = "col-sm-2 col-sm-offset-2">
<button class = "btn btn-primary" type = "submit">Edit changes</button>
</div>
</div>
</form>
<?php
}
else { ?> <div>No Data Available</div> <?php } ?>
get_table_data может возвращать строку (no_data), которая является недопустимым аргументом для foreach. Если это так, заставьте его возвращать пустой массив вместо строки.