2010-04-08 55 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方法中做條件。