doudg60800 2011-10-05 11:38
浏览 36
已采纳

让一个php类返回数组值并保持循环直到结束

I'm trying to create a website that allows for easy theme adding/manipulation like wordpress and other CMS systems do. To do this I'd like to make it so the theme file that delivers the content uses as little php code as possible. At the moment this is the (extremely simplified) class

class getparents {
        var $parentsarray;

   function get_parents() {
                $this->parentsarray = array();
                $this->parentsarray[] = array('Parent0',3,1);
                $this->parentsarray[] = array('Parent1',8,2);
                $this->parentsarray[] = array('Parent2',2,3);
                return $this->parentsarray;
        }
}

And retrieving it like this:

$parents = new getparents();

?><table><?php
foreach($parents->get_parents() as $rowtable)
{
    echo "<tr><td>$rowtable[0] has category ID $rowtable[1] and is on level $rowtable[2] </td></tr>";
}
?></table><?php

But I want to make the retrieving more like this:

<table>
    <tr><td><?php echo $cat_title; ?> has category ID <?php echo $cat_id; ?> and is on level <?php echo $cat_level; ?> </td></tr>
</table>

Which basically mean the class would just return the value in an understandable way and automatically keep on looping without the user having to add *foreach($parents->get_parents() as $rowtable)* or something similar in their theme file.

Here's an example wordpress page to (hopefully) illustrate what I mean. This page retrieves all posts for the current wordpress category which is what I'm trying to mimic in my script, but instead of retrieving posts I want to retrieve the category's parents, but I don't think it's important to explain that in detail.

<?php
/**
 * The template for displaying Category Archive pages.
 *
 * @package WordPress
 * @subpackage Twenty_Ten
 * @since Twenty Ten 1.0
 */

get_header(); ?>

        <div id="container">
            <div id="content" role="main">

                <h1 class="page-title"><?php
                    printf( __( 'Category Archives: %s', 'twentyten' ), '<span>' . single_cat_title( '', false ) . '</span>' );
                ?></h1>
                <?php
                    $category_description = category_description();
                    if ( ! empty( $category_description ) )
                        echo '<div class="archive-meta">' . $category_description . '</div>';

                /* Run the loop for the category page to output the posts.
                 * If you want to overload this in a child theme then include a file
                 * called loop-category.php and that will be used instead.
                 */
                get_template_part( 'loop', 'category' );
                ?>

            </div><!-- #content -->
        </div><!-- #container -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Note: My actual question doesn't have anything to do with wordpress at all so I didn't add it as a tag.

UPDATE: I think my question may have been unclear. Here's a messy example (that works nevertheless)

index.php

<?php
include_once("class.php");
include_once("config.php");
if(isset($_GET['catid']))
{
    $getproducts = new getproducts($_GET['catid']);
    $catproductsarray = $getproducts->getarray();

    $indexxx = 0;
    foreach($catproductsarray as $rowtable)
    {
        include("templates/$template/all_products.php");
        $indexxx++;
    }
}

class.php

class getproducts {

  var $thearrayset = array();

  public function __construct($indexx) {
    $this->thearrayset = $this->makearray($indexx);
  }

  public function get_id($indexxx) {
    echo $this->thearrayset[$indexxx]['id'];
  }

  public function get_catID($indexxx) {
    echo $this->thearrayset[$indexxx]['catID'];
  }

  public function get_product($indexxx) {
    echo $this->thearrayset[$indexxx]['name'];
  }

  public function makearray($indexx) {
    $thearray = array();
        if(!is_numeric($indexx)){ die("That's not a number, catid."); };
        $resulttable = mysql_query("SELECT * FROM products WHERE catID=$indexx");
        while($rowtable = mysql_fetch_array($resulttable)){
            $thearray[] = $rowtable;
        }

    return $thearray;
  }

  public function getarray() {
    return $this->thearrayset;
  }

}

templates/default/all_products.php

<!-- The below code will repeat itself for every product found -->
<table>
<tr><td><?php $getproducts->get_id($indexxx); ?> </td><td> <?php $getproducts->get_catID($indexxx); ?> </td><td> <?php $getproducts->get_product($indexxx); ?> </td></tr>
</table>

So basically, index.php gets loaded by user after which the amount of products in mysql database is taken from the class. For every product, all_products.php gets called with $indexxx upped by one.

Now the only thing the user has to do is edit the HTML all_products.php and the products will all be displayed differently. This is what I'm going for, but in a clean, responsible way. Not like this, this is a mess!

UPDATE2: I found a better way to do it, but added it as an answer. Seemed more fitting and pevents this question from getting any longer/messyer than it already is.

  • 写回答

1条回答 默认 最新

  • dongpo2458 2011-10-06 21:01
    关注

    Ok I'm getting a little bit closer to what I want, so I'm adding this as an answer.

    The template:

    <?php include("templates/$template/header.php"); ?>
    <!-- [product][description][maxchars=##80##][append=##...##] -->
    <!-- [categories][parents][name][append= ->] --><!-- maxchars=false means dont cut description -->
    <!-- [categories][children][prepend=nothing] --><!-- prepend=nothing means no prepend -->
    
        <div id="middle-left-section">
            <table>
            {start-loop-categories-parents}
            <tr><td><a href="<!-- [categories][parents][url] -->"><!-- [categories][parents][name] --></a></td><td>
            {end-loop-categories-parents}
            </table>
    
            <table>
            <tr><td><!-- [categories][current] --></tr></td>
            {start-loop-categories}
            <tr><td>&nbsp;<!-- [categories][children] --></td><td>
            {end-loop-categories}
            </table>
        </div>
        <div id="middle-right-section">
            <table id="hor-minimalist-a">
            <thead>
            <th scope="col">&nbsp;</th>
            <th scope="col">Name</th>
            <th scope="col" width="200px">Description</th>
            <th scope="col">Price</th>
            </thead>
            <tbody>
            {start-loop-product}
            <tr><td><img src="fotos/<!-- [product][thumb] -->"></img></td><td><!-- [product][name] --></td><td><!-- [product][description] --></td><td><!-- [product][price] --></td></tr>
            {end-loop-product}
            </tbody>
            </table>
        </div>
      <div style="clear: both;"/>
    </div>
    <?php include("templates/$template/footer.php"); ?>
    

    The class:

    <?php
    ///////////////////////////
    //Includes and functions//
    /////////////////////////
    include_once("config.php");
    include_once("includesandfunctions.php");
    
    function get_between($input, $start, $end)
    {
      $substr = substr($input, strlen($start)+strpos($input, $start), (strlen($input) - strpos($input, $end))*(-1));
      return $substr;
    }
    
    function get_between_keepall($input, $start, $end)
    {
      $substr = substr($input, strlen($start)+strpos($input, $start), (strlen($input) - strpos($input, $end))*(-1));
      return $start.$substr.$end;
    }
    
    class listproducts {
    
    var $thearrayset = array();
    var $file;
    var $fp;
    var $text;
    var $products;
    var $productskeepall;
    var $done;
    var $returnthisloopdone;
    
      public function __construct() {
      global $template;
        //Get items from mysql database and put in array
        $this->thearrayset = $this->makearray();
        //Read file
        $this->file  = "templates/$template/all_products.php";
        $this->fp = fopen($this->file,"r");
        $this->text = fread($this->fp,filesize($this->file));
    
        //Set other vars
        $this->products = '';
        $this->productskeepall = '';
        $this->returnthisloopdone = '';
        $this->done = ''; //Start $done empty
    
      }
    
      public function makearray() {
        $thearray = array();
            $resulttable = mysql_query("SELECT * FROM products");
            while($rowtable = mysql_fetch_array($resulttable)){
                $thearray[] = $rowtable; //All items from database to array
            }
        return $thearray;
      }
    
    public function getthumb($indexxx) {
            $resulttable = mysql_query("SELECT name FROM mainfoto where productID=$indexxx");
            while($rowtable = mysql_fetch_array($resulttable)){
                return $rowtable['name']; //Get picture filename that belongs to requested product ID
            }
      }
    
        public function listproduct() 
        {
        global $template;
    
            $this->products = get_between($this->done,"{start-loop-product}","{end-loop-product}"); //Retrieve what's between starting brackets and ending brackets and cuts out the brackets
            $this->productskeepall = get_between_keepall($this->done,"{start-loop-product}","{end-loop-product}"); //Retrieve what's between starting brackets and ending brackets and keeps the brackets intact
    
            $this->returnthisloopdone = ''; //Make loop empty in case it's set elsewhere
            for ($indexxx = 0; $indexxx <= count($this->thearrayset) - 1; $indexxx++) //Loop through items in array, for each item replace the HTML comments with the values in the array
            {
                $this->returnthis = $this->products;
    
                $this->returnthis = str_replace("<!-- [product][thumb] -->", $this->getthumb($this->thearrayset[$indexxx]['id']), $this->returnthis);
                $this->returnthis = str_replace("<!-- [product][catid] -->", $this->thearrayset[$indexxx]['catID'], $this->returnthis);
                $this->returnthis = str_replace("<!-- [product][name] -->", $this->thearrayset[$indexxx]['name'], $this->returnthis);
    
                preg_match('/(.*)\[product\]\[description\]\[maxchars=##(.*)##\]\[append=##(.*)##\](.*)/', $this->done, $matches); //Check if user wants to cut off description after a certain amount of characters and if we need to append something if we do (like 3 dots or something)
                $maxchars = $matches[2];
                $appendeez = $matches[3];
                if($maxchars == 'false'){ $this->returnthis = str_replace("<!-- [product][description] -->", $this->thearrayset[$indexxx]['description'], $this->returnthis);
                }else{ $this->returnthis = str_replace("<!-- [product][description] -->",  substr($this->thearrayset[$indexxx]['description'],0,$maxchars).$appendeez, $this->returnthis);
                }
    
                $this->returnthis = str_replace("<!-- [product][price] -->", $this->thearrayset[$indexxx]['price'], $this->returnthis);
    
                $this->returnthisloopdone .= $this->returnthis; //Append string_replaced products section for every item in array
            }
    
            $this->done = str_replace($this->productskeepall, $this->returnthisloopdone, $this->done);
    
            //Write our complete page to a php file
            $myFile = "templates/$template/cache/testfile.php";
            $fh = fopen($myFile, 'w') or die("can't open file");
            $stringData = $this->done;
            fwrite($fh, $stringData);
            fclose($fh);
    
            return $myFile; //Return filename so we can include it in whatever page requests it.
        }
    
    } //End class
    
    ?>
    

    The php requested by the website visitor, which will call the current template's all_products.php

    include_once("class.php");
    
    $listproducts = new listproducts();
    include_once($listproducts->listproduct());
    

    So what this really is, is just string_replacing the HTML comments in the template file with the PHP result I want there. If it's a loop, I Single out the html code I want to loop -> Start an empty string variable -> Repeat that HTML code, appending each loop to the string variable -> Use this string variable to replace the HTML comment

    The newly built page is then written to an actual file, which is then included.

    I'm completely new to OOP, so this is pretty elaborate stuff for me. I'd like to know if this is a good way to tackle my problem. And also, is it possible to prevent having to rewrite that entire class for every page?

    As an example, if I also wanted to build a guestbook I'd like to rewrite the class in a way that it can accept passed variables and build the page from there, rather than pre-setting alot of stuff limiting it to one 'task' such as retrieving products. But before I go any further I'd like to know if this is an a-okay way to do this.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 tensorrt 推理 yolov8框出现错误
  • ¥15 用hc 05,做蓝牙控制小车 小车只能说初始遥控方向影响,后续不能更改
  • ¥15 51单片机怎么把每次输入键值保存到数组作为我的确认键的判断条件呢
  • ¥15 c语言字符串单词入门问题报错
  • ¥30 我现在是双非人工智能专业不知道要不要转到软件工程专业
  • ¥15 请问12脉波整流机组的外特性曲线具体是如何推导
  • ¥15 abaqus里的python算法
  • ¥100 如何在思科模拟器中进入CEF模式
  • ¥15 Simulink 仿真如何使用MATLAB function模块获取到仿真过程中某一仿真时刻输入到模块的函数的值?
  • ¥50 关于#微信小程序#的问题:微信小程序支持h5实现webrtc h264 h265低延迟传输渲染,能付费帮我们解决一下吗