类中的PHP全局变量被重置

时间:2010-04-08 15:03:10

标签: php variables global

我有一个Web表单来处理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 个答案:

答案 0 :(得分:2)

在引用类方法中的实例属性时,必须使用$ this:

$this->isNew = 1;

答案 1 :(得分:2)

这两个变量有两个完全不同的值。成员变量不会覆盖外部作用域中的成员变量,它仅适用于该类的实例。因此,如果要访问全局值,则需要使用关键字global

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

请注意,以这种方式使用全局变量并不是一种好习惯,OOP背后的想法是将类中需要的所有内容放入类中。 OTOH如果此值控制一个函数的行为,您应该将其作为参数传递给该函数而不是访问全局函数。

代码更新后

编辑: 您没有在任何地方设置变量($isNew)。只是一个猜测,但你想在EditForm的开头设置它吗?那一行是$this->isNew = $isNew;

答案 2 :(得分:1)

使用它访问它:

$this->isNew = 1;

答案 3 :(得分:1)

查看http://pastebin.com/40TQFEd5的完整代码,很明显您无法理解PHP流程的工作原理。简而言之,每次加载页面时(通过GET或POST),就像你的程序从头开始。在单独的页面加载之间保留数据的唯一方法是,如果您将其显式存储在要保留的位置 - 例如在服务器端SESSION变量或客户端:  *在链接中输出它,以便可以在GET变量中获取它  *输出表单字段(例如,隐藏字段),以便可以在GET或POST变量中拾取(取决于表单提交方法)  *调用SetCookie()或输出设置cookie的javascript,以便可以在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值的隐藏字段,甚至更好地输出帖子ID值。


顺便说一下,你的代码可以使用一些工作。至少有一个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";
实际上,将那么多表单输出显示为print语句很难阅读和维护。我建议您查看模板引擎:请参阅https://stackoverflow.com/questions/62617/whats-the-best-way-to-separate-php-code-and-htmlhttps://stackoverflow.com/questions/62605/php-as-a-template-language-or-some-other-php-templating-script

答案 4 :(得分:0)

通过定义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()?

答案 5 :(得分:0)

我建议将'new'标志传递给class方法。即

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方法中做有条件的东西了。