Практическое задание №3(Первая CMS): проблемы с редактированием пользователя.

Возникает проблема с редактированием существующих пользователей:
1) Поялвяются надписи: "Trying to get property of non-object", указывающие на строки 28,36,44,60
файла editUser.php.
2) После редактирования пользователя и сохранения изменений, изменения не применяются.

Ссылка на задание: Практическое задание №3

Screenshot-from-2019-05-31-23-18-07

<?php
// показываем только админу
if ($_SESSION['userName'] !== 'admin') {
    header("Location: admin.php");
}
include "templates/include/header.php";
include "templates/admin/include/header.php" ?>

        <h1><?php echo $results['pageTitle']?></h1>

        <form action="admin.php?action=<?php 
                                   echo $results['formAction']?>" method="post">
            <input type="hidden" name="userLogin" value="<?php 
                                               echo $results['user']->login ?>">

    <?php if (isset($results['errorMessage'])) { ?>
            <div class="errorMessage"><?php 
                                          echo $results['errorMessage'] ?></div>
    <?php } ?>

            <ul>

              <li>
                <label for="title">User Login</label>
                <input type="text" name="login" id="login" 
                       placeholder="Login" 
                       required autofocus maxlength="25" value="<?php 
                       echo htmlspecialchars($results['user']->login)?>" />
              </li>
              
              <li>
                <label for="title">User Password</label>
                <input type="text" name="password" id="password" 
                       placeholder="Password" 
                       required autofocus maxlength="25" value="<?php 
                       echo htmlspecialchars($results['user']->password)?>" />
              </li>

              <li>
                  <label for="checkActivity">Active</label>
                  <input type="checkbox" name="active" value="1" 
                         id="checkboxActivity"
                  <?php
                        if($results['user']->active == 1) {
                            echo 'checked = "checked"';
                        }
                  ?>
                  >
              </li>

            </ul>

            <div class="buttons">
              <input type="submit" name="saveChanges" value="Save Changes" />
              <input type="submit" formnovalidate name="cancel" value="Cancel" />
            </div>

        </form>

    <?php if ($results['user']->login) { ?>
          <p><a href="admin.php?action=deleteUser&userLogin=<?php 
            echo $results['user']->login ?>" 
            onclick="return confirm('Delete This User?')">
                  Delete This User
          </a></p>
    <?php } ?>
<?php include "templates/include/footer.php" ?> 

С первой проблемой разобрался при помощи добавления проверки isset:

if (isset($results['user']->login))
echo htmlspecialchars($results['user']->login)

Надписи "Trying to get property of non-object" перестали отображаться.
НО обновление логина и пароля пользователя не происходит про прежнему.

Ссылка на коммит: ПР3

Key Words for FKN + antitotal forum (CS VSU):

vedro-compota's picture

if (isset($results['user']->login))

хочу сразу отметить, что эта проверка не совсем корректна в том смысле , чтобы проверяете существование поля объекта, в то время как у вас судя по ошибке нет самого объекта (хотя isset не упадет вообще на любом несуществующем обращении):

Trying to get property of non-object

чему равна переменная в момент возникновения ошибки? Видимо null?
И далее - почему это происходит? Как именно вы отлаживаете код, выясняете причину? опишите процесс.

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

Ещё просьба добавить ссылку на само задание на сайте.

_____________
матфак вгу и остальная классика =)

Pavel1989's picture

Чему равна переменная в момент возникновения ошибки? Видимо null?

Создание нового пользователя работает. По умолчанию в классе User задается значение null для login, password, active:

class User
    {
    /**
    * @var string логин пользователя
    */
    public $login = null;
    /**
    * @var string пароль
    */
    public $password = null;
    /**
    * @var int активность пользователя: 1 - доступ открыт, 0 - доступ закрыт
    */
    public $active = null;

Абсолютно не функционирует: редактирование уже созданного пользователя, не работает его удаление.

Как именно вы отлаживаете код, выясняете причину? опишите процесс.

Отладчиком не пользуюсь, смотрю на код, анализирую, вношу измение в код, затем сохраняю код в редакторе NetBeans и обновляю страницу в браузере.

Внешне функции редактирования пользователя (файл admin.php) выглядят правильно, самостоятельно найти ошибку не получается:

function editUser()
{
    $results = array();
    $results['pageTitle'] = "Edit User";
    $results['formAction'] = "editUser";
    if (isset( $_POST['saveChanges'])) {
        $user = new User($_POST);
        
// если пользователь меняет логин на занятый выводим форму вновь, если логин 
// не занят - сохраняем
        if ($user->update($_POST)) {
 // логин занят
           header("Location: admin.php?action=editUser&error=loginExists&"
                   . "userLogin=" . $_POST['userLogin']); 
        } else {
           header("Location: admin.php?action=listUsers&status=changesSaved");
        }
        
        } if (isset($_POST['cancel'])) {
        header("Location: admin.php?action=listUsers");
        
        } else {
            
        if (isset($_GET['error'])) {
            if ($_GET['error'] == 'loginExists') {
                $results['errorMessage'] = 'Логин занят';
            }
        }
        $results['user'] = User::getByLogin($_GET['userLogin']);
        require(TEMPLATE_PATH . "/admin/editUser.php");
    }
}
/**
 * Удалить пользователя
 */
function deleteUser()
{
// проверяем существует ли такой пользователь
    if (!$user = User::getByLogin($_GET['userLogin'])) {
        header("Location: admin.php?action=listUsers&error=userNotFound");
        return;
    }
    $user->delete();
    header("Location: admin.php?action=listUsers&status=userDeleted"); 
}
vedro-compota's picture

Отладчиком не пользуюсь, смотрю на код, анализирую, вношу измение в код, затем сохраняю код в редакторе NetBeans и обновляю страницу в браузере.

ну так попробуйте использовать отладчик или распечатывайте промежуточное значение - чтобы понять как именно "по какой ветки логики" движется код. Это важное умение, проект тут простой как раз чтобы потренировать подойдет

_____________
матфак вгу и остальная классика =)

Pavel1989's picture

Попробовал поставить Breakpoints на тех строках, на которые ссылка в тексте ошибки:

image

2

Правильно ли выполняю распечатку объекта? Брейкпоинты лучше ставить в тех строках на которые ссылается ошибка, если я правильно понимаю?

Pavel1989's picture

Сделал отладку файлов editUser.php и User.php с укзанием в watches переменных:

edit-User-php

user-php

Интересен момент: type: null value? Тип переменной: нулевое значение?

vedro-compota's picture

ype: null value? Тип переменной: нулевое значение?

да, т.е. значение null. Что такое null - вспоминаем отдельно. Это что-то типа "без значения".

Там null - т.е. не объект, а у необъекта обратиться к свойству нельзя, о чем и сообщает ошибка:

Trying to get property of non-object

(вы писали о ней выше).
Далее:
почему там null? откуда должны браться данные для формирования объекта? (из базы или из обработки запроса GET или POST при отправки формы) - выяснили это?

_____________
матфак вгу и остальная классика =)

Pavel1989's picture

Там null - т.е. не объект, а у необъекта обратиться к свойству нельзя, о чем и сообщает ошибка:

Если я правильно понимаю, то login, password, active это свойства класса User и им задается первоначальное значение null, и далее конструктор присваевает им реальные
значения из массива $data. (также реализованно и для классов Category, Article).

class User
    {
    
    public $login = null;
    /**
    * @var string пароль
    */
    public $password = null;
    /**
    * @var int активность пользователя: 1 - доступ открыт, 0 - доступ закрыт
    */
    public $active = null;
    
    
    public function __construct($data = [])
    {
  
        if (isset($data['login'])) {
            $this->login = $data['login'];
        }
        
        if (isset($data['password'])) {
            $this->password = $data['password'];
        }
        
        if (isset($data['active'])) {
            $this->active = $data['active'];
        } else {
            $this->active = 0;
        }
    }
почему там null? откуда должны браться данные для формирования объекта? (из базы или из обработки запроса GET или POST при отправки формы) - выяснили это?

Обработка POST запроса при отправке формы:

        
<form action="admin.php?action=<?php 
echo $results['formAction']?>" method="post">
vedro-compota's picture

Добавляю этот комментарий сильно позже на будущее: используйте такой приём для передачи значения по умолчанию.

_____________
матфак вгу и остальная классика =)