Глобальная переменная PHP в классе сбрасывается - PullRequest
0 голосов
/ 08 апреля 2010

У меня есть веб-форма, которая управляет записями в базе данных MySQL. У меня есть метод для отображения интерфейса редактирования как для создания новых записей, так и для их редактирования

if ($_POST['new_page']) {
        print "<h2>Create new page</h2>\n";
        $isNew=1;
        $this->EditForm();
    } else if($_POST['edit']){
        print "<h2>Edit page</h2>\n";
        $isNew=0;
        $this->EditForm();
    }

Я пытаюсь использовать глобальную переменную $ isNew, чтобы определить, где запись должна быть добавлена ​​или обновлена. Однако всякий раз, когда выполняется моя функция SaveChanges (), $ isNew всегда равен 0. $ isNew объявляется сразу после объявления класса, вне всех функций.

class Editor{
    public $isNew;

Пример полного кода (от http://pastebin.com/40TQFEd5):

When the object is created in index.php, the method HTMLEditorHandler() is called

<?php 

class HTMLEditor{

    var $isNew;

    function SaveChanges($author, $company, $title, $content, $new){
        // Get AuthorID
        // Search database for ID 
        $sql="SELECT ID";
        $sql.=" FROM authors";
        $sql.=" WHERE Name = '$author'";
        $author_id=$this->db->getOne($sql);
        // If author not found, add to database
        if(!$author_id){
            $sql="INSERT INTO authors(Name)";
            $sql.="VALUES ('{$author}')";
            $this->db->query($sql);
            $author_id=mysql_insert_id();
        }
        print "isNew: ".$this->isNew;
        /*if($this->isNew==1){
            $sql="INSERT INTO pages(CompanyID, AuthorID, Title, Content, DateCreated, DateUpdated)";
            $sql.=" VALUES ('{$company}', '{$author_id}', '{$title}', '{$content}', NOW(), NOW())";
            $this->db->query($sql);
        } else if($this->isNew==0){
            print "Not new";
        }*/
    }

    function EditForm($isNew){
        if(isset($_POST['pageID'])){
            $sql="SELECT Name, Title, Content, CompanyID";
            $sql.=" FROM pages, authors\n";
            $sql.=" WHERE pages.AuthorID = authors.ID";
            $sql.=" AND pages.ID = '".$_POST['pageID']."'";

            $result=$this->db->query($sql);
            $row=$result->fetchRow();
            $company=$row['CompanyID'];
        }
        print "<form action=\"{$_SERVER['PHP_SELF']}\" method=\"post\">\n";
            print "<table width=\"100%\"summary=\"New Page\"\n>";
                print "<tr>\n";
                    print "<th>Author: </th>\n";
                    print "<td><input type=\"text\" name=\"author\"";
                        if(isset($row['Name'])){
                            print "value=\"".$row['Name']."\"";
                        }
                    print "/></td>\n";
                print "</tr>\n";
                print "<tr>\n";
                    print "<th>Company: </th>\n";
                    print "<td>\n";
                        $this->ShowCompanies($company);
                    print "</td>\n";
                print "</tr>\n";
                print "<tr>\n";
                    print "<th>Title: </th>\n";
                    print "<td><input type=\"text\" name=\"title\"";
                        if(isset($row['Title'])){
                            print "value=\"".$row['Title']."\"";
                        }
                    print "/></td>\n";
                print "</tr>\n";
                print "<tr>\n";
                    print "<th>Content: </th>\n";
                    print "<td>\n";
                        print $this->myToolBar->EditableArea("content", htmlspecialchars($row['Content']), "100%", 400, "NoSave");
                    print "</td>\n";
                print "</tr>\n";
            print "</table>\n";
            print "<input type=\"submit\" name=\"save\" value=\"Save\"/>\n";
            print "<input type=\"submit\" name=\"\" value=\"Cancel\"/>\n";
        print "</form>\n";
    }

    function DefaultForm(){
        print "<form action=\"{$_SERVER['PHP_SELF']}\" method=\"post\">\n";
            print "<input type=\"submit\" name=\"new_page\" value=\"Create a new page\"/>";
            print "<h2>Edit an existing page</h2>\n";
            print "<table summary=\"Edit Page\">\n";
                print "<tr><th>Year</th><td>";
                    print "<select name=\"year\" onchange=\"showPages()\" id=\"year_select\">\n";
                    for ($year=date('Y'), $max_year=date('Y')-10; $year > $max_year; $year--) { 
                            print "<option value=\"".$year."\">".$year."</option>\n";
                        }
                    print "</select>\n";
                print "</td></tr>";
                print "<tr><th>Company: </th><td>";
                    $sql="SELECT organisations.OrgID, companynames.CompanyName";
                    $sql.=" FROM qsvision.organisations";
                    $sql.=" LEFT JOIN qsvision.companynames";
                    $sql.=" ON qsvision.organisations.CompanyID=qsvision.companynames.CompanyID";
                    $sql.=" WHERE CompanyName!=''";
                    $sql.=" GROUP BY companynames.CompanyID";
                    $sql.=" ORDER BY companynames.CompanyName ASC";
                    $organisations=$this->db->getAll($sql);

                    print "<select name=\"org_id\" onchange=\"showPages()\" id=\"org_id\">\n";
                        print "<option value=\"\">[Select...]</option>\n";
                        for($i=0, $max_i=count($organisations); $i<$max_i; $i++){
                            print "<option value=\"{$organisations[$i]['OrgID']}\"";
                            if($site['OrgID']==$organisations[$i]['OrgID']){
                                print " selected=\"selected\"";
                            }
                            print ">".htmlspecialchars($organisations[$i]['CompanyName'])."</option>\n";
                        }
                    print "</select>\n";
                print "</td></tr>\n";
                print "</table>";
                print "<div id=\"results_table\"></div>";
        print "</form>";
    }

    function HTMLEditorHandler(){
        if ($_POST['new_page']) {
            print "<h2>Create new page</h2>\n";
            $this->EditForm(true);
        } else if($_POST['edit']){
            print "<h2>Edit page</h2>\n";
            $this->EditForm(false);
        } else if($_POST['delete']){
            $this->DeletePage();
            $this->DefaultForm();
        } else if($_POST['save']){
            $this->SaveChanges($_POST['author'], $_POST['org_id'], $_POST['title'], $_POST['content'],$this->isNew);
            $this->DefaultForm();
        } else {
            $this->DefaultForm();
        }
    }
}

?>

Ответы [ 6 ]

2 голосов
/ 08 апреля 2010

Эти две переменные имеют два совершенно разных значения. Переменная-член не переопределяет переменную во внешней области, она существует только для экземпляра этого класса. Поэтому, если вы хотите получить доступ к глобальному значению, вам нужно использовать ключевое слово global :

class Editor {
    public function foo() {
        global $isNew;
        if ($isNew) {
            # ...
        }
    }
}

Обратите внимание, что использование глобалов таким способом не является хорошей практикой, идея ООП заключается в том, что вы помещаете в класс все, что вам нужно внутри класса. OTOH, если это значение управляет поведением только одной функции, вы должны передать ее в качестве параметра этой функции, а не обращаться к глобальной.

РЕДАКТИРОВАТЬ после обновления кода: Вы нигде не устанавливаете свою переменную ($isNew). Просто предположение, но вы хотели установить его в начале EditForm? Эта строка будет $this->isNew = $isNew;.

2 голосов
/ 08 апреля 2010

Вы должны использовать $ this, когда ссылаетесь на свойства экземпляра внутри метода класса:

$this->isNew = 1;
1 голос
/ 08 апреля 2010

Глядя на ваш полный код из http://pastebin.com/40TQFEd5,, становится ясно, что вы не понимаете, как работает поток процессов PHP. Короче говоря, каждый раз, когда страница загружается (GET или POST), создается впечатление, что ваша программа запускается с нуля. Единственный способ сохранения данных между отдельными загрузками страниц - это если вы явно сохраняете их где-то для сохранения - например, в переменной SESSION на стороне сервера или на стороне клиента: * вывести его в виде ссылки, чтобы его можно было найти в переменной GET * вывести поле формы (например, скрытое поле), чтобы его можно было найти в переменной GET или POST (в зависимости от метода отправки формы) * вызвать SetCookie () или вывести javascript, который устанавливает cookie, чтобы его можно было найти в переменной COOKIE

Соответствующий бит кода:

    if ($_POST['new_page']) {
        print "<h2>Create new page</h2>\n";
        $this->EditForm(true); 
    } else if($_POST['edit']){
        print "<h2>Edit page</h2>\n";
        $this->EditForm(false);
    } else if($_POST['save']){
        $this->SaveChanges($_POST['author'], $_POST['org_id'], $_POST['title'], $_POST['content'],$this->isNew);
        $this->DefaultForm();

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

  • Страница загружена со значением POST 'edit' или 'new_page'. Создается новый экземпляр класса HTMLEditor, и (хотя ваш код фактически не делает этого сейчас) $ isNew устанавливается соответствующим образом на основе значения POST. Форма выводится на страницу и отправляется клиенту
  • Пользователь заполняет форму в браузере и нажимает кнопку "Отправить"
  • Страница загружена со значением POST 'save'. Создан новый экземпляр класса HTMLEditor. isSet неизвестен, так как он не был сохранен и снова отправлен на сервер.

Очень простое решение: в вашем методе EditForm() выведите скрытое поле, содержащее значение isSet или, что еще лучше, значение идентификатора записи.


Кроме того, ваш код может использовать некоторую работу. Существует по крайней мере одна уязвимость в SQL-инъекции:

$sql.=" AND pages.ID = '".$_POST['pageID']."'";

Отступы ваших операторов печати на основе HTML затрудняют чтение кода:

        print "<table width=\"100%\"summary=\"New Page\"\n>";
            print "<tr>\n";
                print "<th>Author: </th>\n";
                print "<td><input type=\"text\" name=\"author\"";
                    if(isset($row['Name'])){
                        print "value=\"".$row['Name']."\"";
                    }
                print "/></td>\n";

и, действительно, вывод такого большого количества форм, отображаемых как операторы печати, трудно читать и поддерживать. Я бы посоветовал вам взглянуть на шаблонизатор: см. https://stackoverflow.com/questions/62617/whats-the-best-way-to-separate-php-code-and-html или https://stackoverflow.com/questions/62605/php-as-a-template-language-or-some-other-php-templating-script

1 голос
/ 08 апреля 2010

доступ к нему с этим:

$this->isNew = 1;
0 голосов
/ 08 апреля 2010

Я бы рекомендовал передать флаг 'new' в метод класса. то есть.

class Editor {
  public function edit($new = false) {
    if ($new) {
      print "<h2>Create new page</h2>\n";
      $this->edit_form();
    } else {
      print "<h2>Edit page</h2>\n";
      $this->edit_form();
    }
  }

  public function edit_form() {
    // form stuff
  }
}

Вы можете просто вызвать edit_form () и передать туда флаг. Таким образом, вы также можете делать условные вещи в вашем методе edit_form.

0 голосов
/ 08 апреля 2010

Определяя public $isNew, вы создаете свойство класса, а не глобальное.Доступ к свойствам класса осуществляется с помощью ключевого слова $this, как вы это делали при вызове метода.Вы хотели сделать это:

class Editor {
    public $isNew;

    function whatever() {
        if ($_POST['new_page']) {
            print "<h2>Create new page</h2>\n";
            $this->isNew=1;
            $this->EditForm();
        } else if($_POST['edit']){
            print "<h2>Edit page</h2>\n";
            $this->isNew=0;
            $this->EditForm();
        }
    }

    function EditForm() {
        echo $this->isNew;
    }
}

Есть ли какая-то причина, по которой вы не просто передаете флаг "new" в EditForm () в качестве аргумента?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...