2010-04-08 84 views
0

我有一个web表单来操作MySQL数据库中的记录。我有用于显示这两个创造新记录的编辑界面和编辑它们PHP中的全局变量被重置

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(); 
    } 

我想使用全局变量$是否新款,以确定一个记录将被添加或更新的方法。但是,只要我的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(); 
     } 
    } 
} 

?> 
+2

好像你就像失踪OOP – Kemo 2010-04-08 15:05:48

+2

点好像你就像失踪计算器 – Robert 2010-04-08 15:09:58

+0

点我相信你混淆了关键字static,全球和公共的。 – 2010-04-08 15:22:48

回答

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(); 
从你甚至没有设置$是否新款variab问题

除了在你的代码示例中,真正的问题是流程如下工作:

  • 页面被加载,POST值为'edit'或'new_page'。创建了HTMLEditor类的新实例,并且(尽管您的代码现在不实际执行此操作),$ isNew根据POST值进行适当设置。表单输出到页面,并发送到客户端
  • 用户填写表单在浏览器中,并点击提交
  • 页面加载,与POST值'保存'。将创建一个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"; 

而事实上,具有显示为打印报表多格式输出很难阅读和维护。我建议你寻找到一个模板引擎:见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

+0

非常感谢。我没有意识到我在做什么是错的,你的建议已经解决了我的问题。我已经向我的上级指出了SQL注入漏洞,我不认为这会是一个问题,因为这只会在内部使用,并且我们启用了魔术引号。至于印刷报表,我也不喜欢它们,但它们是公司风格指南=(。 我非常感谢你帮助我进一步了解和理解PHP =) – Robert 2010-04-12 09:23:41

2

你必须使用$此,引用到内的实例属性时一类方法:

$this->isNew = 1; 
+0

这没什么差别 – Robert 2010-04-08 15:10:16

+0

然后我们需要看到更多的代码。 – webbiedave 2010-04-08 15:10:56

+0

我有一个创建新记录的按钮 print“”; 和一个编辑页面的按钮 print“”; 他们都调用输入/编辑记录的方法相同,该记录有一个保存按钮 print“ \ n” ; ($ _ POST ['save']){ \t \t \t $ this-> SaveChanges(//要保存的数据); 但打印语句显示只要调用此方法,$ isNew就被设置为空 – Robert 2010-04-08 15:18:40

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; 
    } 
} 

没有任何理由不your're只是路过“新”标志EditForm()作为参数?

+0

保存记录的功能只被调用一次,因为创建和编辑记录都使用相同的编辑功能。我不能看到我怎么能通过它一个变量 – Robert 2010-04-08 15:23:36

+0

定义:'函数EditForm($ is_new){echo $ is_new; }'。调用:'$ this-> EditForm(1);'。 – 2010-04-08 15:25:16

+0

EditForm()有一个提交按钮,用于在$ _POST ['save']上运行save方法。它不关心我传递给EditForm(),因为EditForm()不调用SaveChanges() – Robert 2010-04-08 15:30:17

2

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

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

注意,使用全局变量这种方式是不好的做法,背后OOP的想法是,你把你需要的类内的一切进入课堂。 OTOH如果该值控制一个函数的行为,则应该将其作为参数传递给该函数,而不是访问全局函数。

编辑后代码更新: 你没有设置你的变量($isNew)的任何地方。只是猜测,但是你想在EditForm的开始处设置它吗?该行将是​​。

+0

我以为它在类中?此外,保存记录的功能仅被调用一次,因为创建和编辑记录都使用相同的编辑功能。我不知道如何将它传递给变量 – Robert 2010-04-08 15:22:52

+0

@Robert:我认为我们需要看到完整的功能。你能编辑你的问题来添加缺失的信息吗? – soulmerge 2010-04-08 15:30:05

0

我建议将'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方法中做条件。