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.

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

报告相同问题?

悬赏问题

  • ¥20 易康econgnition精度验证
  • ¥15 线程问题判断多次进入
  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致