Hello all, I am trying to learn how to use the OOP in php. Hence I have this structural simple CRUD admin table. I am trying to reorganize them with OOP.

structural_admin.php

<?php         

      include('../includes/koneksi.php');



        //Hapus berita // undefined index: mode



    if (!empty($_REQUEST['id']) && !empty($_REQUEST['mode']) && $_REQUEST['mode'] == "delete")
        {
        $id = $_REQUEST['id'];
        $result = mysql_query("DELETE FROM static_page WHERE id =".$id) or die(mysql_error());

        $confirmation = !$result ? "Gagal menghapus data." : "Data telah terhapus."; 
        }


?>
<div align="center">
    <div style="width:700px;text-align:left;padding-top:5px;">
        <?php  if (isset($confirmation)) { echo $confirmation; } ?>  
        <form method="get" action="<?php $_SERVER['PHP_SELF'] ?>">

                                    <br/>
                        <a class="topLink" href="input_berita_static.php">Berita Static Baru >></a><br><br>

        <?php
                //LOAD NEWS

                $result = mysql_query("SELECT * FROM static_page") or die(mysql_error());
                ?>
                <table id="admintable" border="1" cellpadding="2" cellspacing="0">
                    <tr>
                        <th>Page</th><th>Action</th>
                    </tr>
                    <?php
                    $i=0;
                    while ($data = mysql_fetch_array($result)){
                    $result2=($i%2)?'#DFA09D':'white';

                            echo "<tr bgcolor='$result2'>";                  
                            echo '<td>'.$data['page'].'</td>';
                            echo '<td><a href="admin.php?mode=delete&id='.$data['id'].'">Hapus</a> |<a href="input_berita_static.php?id='.$data['id'].'">Edit</a></td>';
                        echo '</tr>';

                    $i++;   
                    }
                    ?>
                </table>

        </form>
    </div>
</div>
  </center>
</div>  


</div>

Here is what did :

OOP_admin.php

class table{
// define properties

function __autoload(){
        echo "has not been defined yet";
        }

function load_row(){
        $sql = mysql_query("SELECT * FROM static_page") or die(mysql_error());


        }


function delete_row() {



        }

}

I am confuse which part I need to copy and paste, and which part I need to leave to be written outside of the php class. Can anyone help me reorganize them?

Also, if I am using form to input data, do I need to utilize OOP class system. if so how to type the code among the input form html codes?

Hi,

Too many other ways of doing this. We can make it at lot simpler, but I don't like auto loading whenever a db connector is involve, I rather write it in basic class and then deliver the instance of the class by Singleton.

kinda like this... you should convert the mysql to mysql PDO.. I don't have my PDO reference, so I will have to do it in the old ways which I can remember easily.

You must remove the error announcement or modify it to something else to prevent actual error broadcast on failed attempt. Please take note of any syntax errors... I don't have the chance testing it....

This is pretty much the semi-model of the application. If you are to use the pure MVC design pattern the Admin.class.php should be included in the model, and the instantiator is the helper to the model, after the controller sort all the url requests and acted with the proper routing response.

WARNING! CODES BELOW ARE NOT TESTED.. IT CAN, OR IT MAY HAVE SOME ERRORS ON IT. IT is provided as a guidelines only and NOT intended for production server, until all security issues are considered.

filename: Database.class.php

<?php

    class Database{

    private $results, $inserted_id, $connection_id;

    public function __construct(){
    }

    public function Connect($host, $user, $password, $database) {
        $this->connection_id = @mysql_connect($host, $user, $password) or $this->db_error(mysql_error()) ;
        @mysql_select_db($database) or $this->db_error(mysql_error()) ;
        $host = '';
        $user = '';
        $password = '';
        $database = '';
    }

    /*
    *@ method query :  prepare the database query
    *
    */
    public function query($query) {
        $this->results = mysql_query($query, $this->connection_id) ;
        $this->inserted_id = mysql_insert_id($this->connection_id) ;
        if ($this->results == false) {
            $this->query_error(mysql_error(), $query) ;
        }
        else {
            return true ;
        }
    }

    /*
    *@ method fetchall :  returns an array of the given query
    *
    */

    public function fetch_all($mode = MYSQL_ASSOC ) {
        $arr = array() ;
        while ($row = $this->fetch($mode)) {
            $arr[] = $row ;
        }
        return $arr ;
    }

    /*
    *@ method fetch_single :  returns a single itme of the given query
    *
    */
    public function fetch_single($mode = MYSQL_ASSOC ) {
        return mysql_fetch_array($this->results, $mode) ;
    }
    /*
    *@ method inserted_id : return the last id of the insert query 
    * 
    */
    public function inserted_id() {
    return $this->inserted_id ;
    }

    /*
    *@ method free_result : .. make sure to call 
    * this method to free up the cache
    */

    public function free_result() {
        return mysql_free_result($this->results) ;
    }

    /*
    *@ method disconnect : .. make sure to call 
    * this method to close the connection
    */

    public function disconnect() {
        $ret = mysql_close($this->connection_id) ;
        $this->connection_id = NULL ;
        return $ret ;
    }

    ## you must change this error announcement
    public function db_error($error) {
        die($error) ;
    }
    ## change error to something else
    public function query_error($error, $query) {
        die('<p>'.$error.'</p>') ;
    }
}

We can create the Singleton instantiator. This is the class responsible in routing the classes as needed by the application

filename: Instantiator.class.php

 <?php

     final class Instantiator{

         /*@class_instance : instiate the classes  requested by application
         *
         */
         private static $class_instance = array();

         ## we set the constructor as private. !Warning, it does not mean it is not overloaded,

         private function __construct(){}

         ## the actual Singleton like a factory

         public static function instance($class){

                ## the instance of the class requested
                self::Instantiate($class);    

                ## we return ONE instance ONLY
                return self::$class_instance[$class];
            }

             ## finally, we make instantiate method to check if the requested class if it exists

             private static function Instantiate($class)
                {
                    ## make sure the requested class exists
                    if (!array_key_exists($class , self::$class_instance))
                    {
                    ## and finally the class being requested is now instantiated
                        self::$class_instance[$class] = new $class;
                    }
                }
            } 

We can make another file called Admin.class.php

 <?php


     require_once('Instantiator.class.php');
     require_once('Database.class.php');

     class Admin{

     ## define vars here as needed by your application

     public function __construct(){
     ## this is a loaded constructor, but we will make sure,we  ONLY have one instance of our database
     $this->db = Instantiator::instance('Database');

     }

     ## if the server is eating too much resources, move the codes from the constructor to the method needing the database. before doing so, you will have to create another method responsible for the db connection
     ## something like this

     function get_dbCon(){
         return(Instantiator::instance('Database'));

         }

      ## create the delete function
      ## USE $_POST instead this is really dangerous..

      public function get_delrequest(&$req_vars){
       ## I have reasons for using the php reference function here. you can easily expand this function accross the site, just by referencing on whatever this method get.

       if (!empty($_REQUEST['id']) && !empty($_REQUEST['mode']) && $_REQUEST['mode'] == "delete"){
          $req_vars['id'] = $_REQUEST['id']; 
          $req_vars['mode'] = $_REQUEST['mode'];
          $req_vars['confirm'] = true;

          }

      }

      public function delete(){
      $deleted = false;
      ## check if the submit button is submitted
      $req_vars = array();
      if(isset($_POST['submit'])){

      $this->db->query("DELETE FROM static_page WHERE id =".$id);

      $deleted = true;

      }
      return $deleted;
      }

        ## create the method to get news

       public function get_news(){

       $this->db->query("SELECT * FROM static_page");

       return $this->db->fetch_all;

       }

       }

To use the class, just include the Admin.class.php and just do it like this.

<?php

include_once('Admin.class.php');

$news = Instantiator::instance('Admin');

## store the news items to some variable or you loop over it
$news_items = $news->get_news();

foreach($news_items as $item){
echo $item['page'].'<br/>';
ehco $item['id'];

}

If you noticed, the codes in OOP is very lengthy. However, there are benefits by separating your logic from the views.

If you will be using any of the template engines, we could pass the data from the admin class to the template engine.

ERROR spotted already.. Admin.class.php

in the constructor, you will need to add this to connect, fill in your database credentials....

$this->db->Connect($host, $user, $password, $database);

what do you mean by the template enginee ? You mean Joomla, wordpress, and opencart? do you mean I can combinee my own OOP PHP with the template enginee ?

template engines are twig, smarty, tinybutstrong, and raintpl..

example of usage,,, say we use my pretty old version class above to fetch somethng from the database..

public function fetch_all($mode = MYSQL_ASSOC ) {
$arr = array() ;
while ($row = $this->fetch($mode)) {
$arr[] = $row ;
}
return $arr ;
}

if we use the above method and implement it to template engine, it will be something like this.. this is an old youtube search query I wrote long time ago while I was in high school.

Let us pretend this is our search.php page

$typestring = "AND (mediatype='video') " ;
        $dbFilters= "title,description,id,groupid,group_id,category,thumb, poster,embprovider, allviews, mediatype,cat_id,cat_name";
        $keywordsearch = "AND (title LIKE '%".$keywords."%' OR description LIKE '%".$keywords."%' OR tags LIKE '%".$keywords."%')" ;
        $getItems =("SELECT ". $dbFilters ." FROM media LEFT JOIN `group` ON (`media`.`groupid` = `group`.`group_id`)LEFT JOIN `category` ON (`media`.`category` = `category`.`cat_id`) WHERE `status` ='true' ".$hide." AND (`suspended`!=1 OR `suspended` IS NULL) ".$keywordsearch." ". filter_var($filterstring, FILTER_SANITIZE_STRIPPED) ." LIMIT $offset,$rowsPerPage") ;

Smarty Template engine example:

We create an object or rather an instance of the classs.

$db = new Database();

Smarty->assign('search_results',$db->fetch_all($getItems);
Smarty->display('search.tpl');

our Smarty template page search.tpl file

<ul>
{foreach $search_results as $item}
<li>{$item.title}</li>

{/foreach}

Twig Example Normally, my implmentation of twig is little different than what was on the manual. First I would create a bootstrapfile to hold the twig object or instance..

## define the location of the twig autoloader file

require_once dirname(__FILE__).'/twig/lib/Twig/Autoloader.php';

function set_template($theme,$theme_file,$content=array(),$cache){

if($cache == true){
$cache_dir = dirname(__FILE__).'/themeslocationDirectory/'.$theme.'/theme_cache';
}
else{
$cache_dir = false;

}
try{

Twig_Autoloader::register(true);
$loader = new Twig_Loader_Filesystem(dirname(__FILE__).'themesLocationdirectory/'.$theme.'/');
$twig = new Twig_Environment($loader, array(
    'cache' => $cache_dir,//dirname(__FILE__).'themeCacheLocationdirectory/'.$theme.'/theme_cache',

));

$twig->addExtension(new Twig_Extension_Text(true)); 

## load template
$theme = $twig->loadTemplate($theme_file);

## echo content 
echo $theme->render($content);

}


catch (Exception $e) {
  die ('ERROR: ' . $e->getMessage());
}

}

If you notice above, I set the content as array by default. In doing this I can directly merge my database search query to my twig template engine..

twig search.php

## we include the bootstrap.php
require_once dirname(__FILE__).'/bootstrap.php';

## we create an object of our database class
$db = new Database();

## we create the content for our template
set_template('templateDirectory','search.tpl', array('results' =>$db->fetch_all($getItems)),false); 

The false parameter is the cache method. You set this true in production server if you want more speed. That is the downside of Twig and smarty compared to rainTPL and tinyButStrong.

search.tpl file for twig

<ul >
         {% for item in results %}
         <li>{{ item.title }}</li>
         {% endfor %}

</ul>

RainTPL example search.php

include_once('locationOfRainTemplateClass');
## we create an object of our database class
$db = new Database();

$rain_tpl = new raintpl();
$rain_tpl->assign( array('results' =>$db->fetch_all($getItems)) );

$rain_tpl->draw( "search.tpl" ); // draw the template

RainTPL search.tpl

<ul>
{loop="results"}
 <li> {$value.title} </li>
{/loop}
</ul>

TinyButStrong search.php

 include_once('locationOfTinyButStrongTemplateClass');
 ## we create an object of our database class
 $db = new Database();

 ## create an instance of the tinyButStrongTemplate Class
 $tinyButStronger = new clsTinyButStrong;
 $tinyButStronger->LoadTemplate('search.tpl');
 $tinyButStronger->MergeBlock('searchBlock', array('results' =>$db->fetch_all($getItems)));

TinyButStrong template file search.tpl

 <ul>

 <li>[searchBlock.val]</li>

 </ul>

I have given you examples of the template engines that I highly favored. You choose which one do you think is a lot easier for you to grasp. Most of them have marginal to none documentations..

this

<li>[searchBlock.val]</li>

should read

<li>[searchBlock.val.title]</li>
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.