Php 循环遍历mysqli查询的结果并用表列替换内容标记

Php 循环遍历mysqli查询的结果并用表列替换内容标记,php,content-management-system,mysqli,Php,Content Management System,Mysqli,我参与了使用PL/SQL和Oracle DB开发CMS的工作,我希望使用PHP和MySQL为我自己的CMS复制相同类型的结构。我是一名来自旧程序时代的PHP程序员,现在我正在努力掌握OOPHP 我有三张桌子。一个代表一页。另一个表示可在页面中使用的模板,另一个表示内容。我已经输出了页面的页眉和页脚(存储在页面表中),但是现在我需要用内容填充页面。为此,我需要查询模板表并将html代码分配给一个变量。然后,我需要使用content表将分配给变量(来自templates表)的html代码中的特定标记

我参与了使用PL/SQL和Oracle DB开发CMS的工作,我希望使用PHP和MySQL为我自己的CMS复制相同类型的结构。我是一名来自旧程序时代的PHP程序员,现在我正在努力掌握OOPHP

我有三张桌子。一个代表一页。另一个表示可在页面中使用的模板,另一个表示内容。我已经输出了页面的页眉和页脚(存储在页面表中),但是现在我需要用内容填充页面。为此,我需要查询模板表并将html代码分配给一个变量。然后,我需要使用content表将分配给变量(来自templates表)的html代码中的特定标记替换为另一个表中的内容。例如:

我查询模板表并拉出一个包含html结构的列。在这个结构中,有一些自生成的标记,例如[i1][i2][i3],它们与内容表中的列相关。我的目标是用内容表中每个相关列的相关内容替换这些标记(因此[i1]将被替换为相关行中i1列的内容)。每个页面的内容表中可能有多个条目,因此这些条目按顺序排序

我目前一直在从内容表中提取与特定页面相关的所有内容的数组。我知道如何使用旧的mysql界面按程序执行此操作,但我找不到任何关于如何在mysqli中正确执行此操作的最新帖子。有什么提示吗

以下是我当前的一组课程:

class Connection extends Mysqli{

    public function __construct($mysqli_host,$mysqli_user,$mysqli_pass, $mysqli_db) {
        parent::__construct($mysqli_host,$mysqli_user,$mysqli_pass,$mysqli_db);
        $this->throwConnectionExceptionOnConnectionError();     
        $this->getUser();
    }

    private function throwConnectionExceptionOnConnectionError(){

        if(!$this->connect_error){
            echo "Database connection established<br/>";
        }else{
        //$message = sprintf('(%s) %s', $this->connect_errno, $this->connect_error);
            echo "Error connecting to the database."; 
        throw new DatabaseException($message);
        }
    }
}

class DatabaseException extends Exception{

}

class Page {

    public function __construct() {
        if(isset($_GET['id'])){
            $id = $_GET['id'];
        }else{      
            $id = 1;
        }       
        get_headers($id);
        get_content($id);
        get_footer($id);
    }

    private function get_headers($pageId){ 
        $retrieveHead = $this->prepare("SELECT header FROM pages WHERE page_id=?");
        $retrieveHead->bind_param('i',$pageId);
        $retrieveHead->execute();
        $retrieveHead->bind_result($header);
        $retrieveHead->fetch();
        $retrieveHead->close();
        echo $header;   
    }

    private function get_footer($pageId){ 
        $retrieveFooter = $this->prepare("SELECT footer FROM pages WHERE page_id=?");
        $retrieveFooter->bind_param('i',$pageId);
        $retrieveFooter->execute();
        $retrieveFooter->bind_result($footer);
        $retrieveFooter->fetch();
        $retrieveFooter->close();
        echo $footer;   
    }

    private function get_content($pageId){
        $retreiveContent = $this->prepare("SELECT * FROM content WHERE page_id=? ORDER BY sequence");
        $retreiveContent->bind_param('i',$pageId);
        $retreiveContent->execute();
    }

}
类连接扩展了Mysqli{
公共函数构造($mysqli_主机,$mysqli_用户,$mysqli_通行证,$mysqli_数据库){
父项::_构造($mysqli_主机,$mysqli_用户,$mysqli_通行证,$mysqli_数据库);
$this->throwConnectionExceptionOnOnConnectionError();
$this->getUser();
}
私有函数throwConnectionExceptionOnConnectionError(){
如果(!$this->connect\u错误){
echo“已建立数据库连接
”; }否则{ //$message=sprintf(“(%s)%s”,$this->connect\u errno,$this->connect\u error); echo“连接到数据库时出错。”; 抛出新数据库异常($message); } } } 类DatabaseException扩展异常{ } 类页{ 公共函数构造(){ 如果(isset($\u GET['id'])){ $id=$_GET['id']; }否则{ $id=1; } 获取_头($id); 获取内容($id); 获取页脚($id); } 私有函数get_头($pageId){ $retrieveHead=$this->prepare(“从页面id=?”的页面中选择页眉”); $retrieveHead->bind_参数('i',$pageId); $retrieveHead->execute(); $retrieveHead->bind_result($header); $retrieveHead->fetch(); $retrieveHead->close(); echo$header; } 私有函数get_footer($pageId){ $retrieveFooter=$this->prepare(“从页面id=?”的页面中选择页脚”); $retrieveFooter->bind_参数('i',$pageId); $retrieveFooter->execute(); $retrieveFooter->bind_result($footer); $retrieveFooter->fetch(); $retrieveFooter->close(); echo$footer; } 私有函数get_content($pageId){ $retreiveContent=$this->prepare(“从内容中选择*,其中页面id=?按顺序排列”); $retreiveContent->bind_参数('i',$pageId); $retreiveContent->execute(); } }
根据我对mySQL的记忆,从这里我会做一个for循环,但是我如何使用这种OOP方法来做这件事,然后如何为每个模板进行标记替换

我的表格结构可以在下面找到。希望这能让我更清楚地了解我在寻找什么:


我猜在某种程度上,我的查询可以进行调整,以执行内部联接,这样模板表中的代码列也会被检索,但我以前没有在MySQLi中真正使用联接,因此我不确定是否有特定的方法来编写语法。

您仍然可以使用fetch循环。填充模板应该只是一个简单的例子str_替换它们:

private function get_content($pageId){

        $theTemplate = grabTheTemplate();

        $retreiveContent = $this->prepare("SELECT * FROM content WHERE page_id=? ORDER BY sequence");
        $retreiveContent->bind_param('i',$pageId);
        $retreiveContent->execute();
        $retreiveContent->bind_result($foo, $bar,$baz);
        while ($retreiveContent->fetch()) {
            //$foo, $bar $baz will be populated for this row.
            //Update the tags in the template.
            $theTemplate = str_replace('tagToReplace','valueToReplaceWith',$theTemplate);
        }
        //$theTemplate is populated with content. Probably want to echo here
        echo $theTemplate;
}

您仍然可以使用fetch循环。填充模板应该只是str_替换它们的一种情况:

private function get_content($pageId){

        $theTemplate = grabTheTemplate();

        $retreiveContent = $this->prepare("SELECT * FROM content WHERE page_id=? ORDER BY sequence");
        $retreiveContent->bind_param('i',$pageId);
        $retreiveContent->execute();
        $retreiveContent->bind_result($foo, $bar,$baz);
        while ($retreiveContent->fetch()) {
            //$foo, $bar $baz will be populated for this row.
            //Update the tags in the template.
            $theTemplate = str_replace('tagToReplace','valueToReplaceWith',$theTemplate);
        }
        //$theTemplate is populated with content. Probably want to echo here
        echo $theTemplate;
}

在Jim的帮助下,我想出了最终的解决方案:

    private function get_content($pageId){
         $retreiveContent = $this->prepare("SELECT template_id, section_title, i1, i2 FROM content WHERE page_id=? ORDER BY sequence");
         $retreiveContent->bind_param('i',$pageId);
         $retreiveContent->execute();
         $retreiveContent->bind_result($template_id, $section_title, $i1, $i2);
            while ($retreiveContent->fetch()) {
            //Variables will be populated for this row.
            //Update the tags in the template.
         $theTemplate = grabTheTemplate($template_id);
         $theTemplate = str_replace('[i1]',$i1,$theTemplate);
         $theTemplate = str_replace('[i2]',$i2,$theTemplate);
         //$theTemplate is populated with content. Probably want to echo here
        echo $theTemplate;
    }


}

由于一个页面上可能有多个内容项,每个内容项都可能有不同的模板,因此我将grabTheTemplate函数调用移动到while循环中,以便可以使用template_id列中的值检索相关模板。我还没有在测试服务器上尝试过这一点,但理论上它应该都可以工作。我今晚我将尝试一下,如果有任何错误,我将编辑这篇文章。

在Jim的帮助下,我找到了最终的解决方案:

    private function get_content($pageId){
         $retreiveContent = $this->prepare("SELECT template_id, section_title, i1, i2 FROM content WHERE page_id=? ORDER BY sequence");
         $retreiveContent->bind_param('i',$pageId);
         $retreiveContent->execute();
         $retreiveContent->bind_result($template_id, $section_title, $i1, $i2);
            while ($retreiveContent->fetch()) {
            //Variables will be populated for this row.
            //Update the tags in the template.
         $theTemplate = grabTheTemplate($template_id);
         $theTemplate = str_replace('[i1]',$i1,$theTemplate);
         $theTemplate = str_replace('[i2]',$i2,$theTemplate);
         //$theTemplate is populated with content. Probably want to echo here
        echo $theTemplate;
    }


}

由于一个页面上可能有多个内容项,每个内容项都可能有不同的模板,因此我将grabTheTemplate函数调用移动到while循环中,以便可以使用template_id列中的值检索相关模板。我还没有在测试服务器上尝试过这一点,但理论上它应该都可以工作。我今晚我会试试,如果有任何错误,我会编辑这篇文章。

嗨,吉姆,谢谢你的回复。我今晚回家后会试试。不过有一件事我想检查一下,$foo、$bar和$baz变量指的是什么?你似乎没有在其他任何地方使用它们…@jme1988这些只是你的列将存储的变量我不知道你的列会是什么,所以只使用了无意义的名称。这不是我想要的。我已经在上面添加了我的表结构。希望这能让它更清晰。我认为