Jump to content

Hall of Famer

Members
  • Posts

    314
  • Joined

  • Last visited

Posts posted by Hall of Famer

  1. Well I have a code that looks like this:

     

    <div style='width:100%; text-align:center; float:left;'>{$array[0][0]}</div>
    <div style='width:50%; text-align:center; float:left;'>{$array[1][0]}</div>
    <div style='width:25%; text-align:center; float:left;'>{$array[2][0]}</div>
    <div style='width:12.5%; text-align:center; float:left;'>{$array[3][0]}</div>
    

     

    As you can see, the width percentage decreases by half as the first index of $array increases by 1. I was wondering if its possible to write a PHP code such that the width percentage is automatically adjusted based on the first index of array. I've tried the following way as below, but it wouldnt work:

     

    <div style='width:{100/(2^$i)}%; text-align:center; float:left;'>{$array[$i][$j]}</div>
    

     

    So do anyone of you know how to do this? Please help.

  2. Well I dont think you get the point I am making. It is not the data type the user inputs that I need to validate, I already know what to do with this. The problem is that they can use firebug or inspect element to change the hidden values in a form, such as an id that they are not supposed to know what it is. Is there a way to prevent them from using firebug and inspect element?

  3. I see, mind showing me an example of data validation given the following form submission example below?

     

    		$article_content = $article_content."<br><img src='{$adoptimage}' border='0'><br>
    		<form name='form1' method='get' action='poundpost.php'>
    		  <p>
    			<input name='aid' type='hidden' id='aid' value='{$row['aid']}'>
    			<input name='type' type='hidden' id='type' value='{$row['type']}'>
    			<input name='name' type='hidden' id='name' value='{$row['name']}'>
    			<input name='currentlevel' type='hidden' id='currentlevel' value='{$row['currentlevel']}'>
    		  </p>
    		  <p>
    			<input type='submit' name='Submit' value='Adopt Me'>
    		</p>
    		</form>";
    	}
    

  4. Hi there, I've looked into the PHP superglobal array $_SERVER, but could not find a variable that stores the plugins a client has on his/her browser such as firefox and google chrome. The point here is to detect if a user has hacking addons such as firebug and inspect element installed, and displays an error message telling the user to disable such plugins in order to access site content. Is it possible to accomplish such tasks? Please help.

  5. Well to make things clear, I have the select() method that looks like this right now:

     

      public function select($action = ""){
        if(empty($this->column)) $this->column = "*";
        $query = "SELECT {$this->column} FROM {$this->table}";
    $query .= (!empty($this->where))?" WHERE {$this->where}":"";
    $query .= (!empty($this->order))?" ORDER BY {$this->order}":"";
    $query .= (!empty($this->limit))?" LIMIT {$this->limit}":"";
        echo $query."<br>";
        $this->result = $this->mysqli->query($query);
        if($action == "row") $result = $this->result->fetch_row(); 
        if($action == "assoc") $result = $this->result->fetch_assoc();
        if($action == "array") $result = $this->result->fetch_array();
        if($action == "object")  $result = $this->result->fetch_object();
        if($action == "num") $result = $this->result->num_rows();
        $this->reset();
        return $result;
      }
    

     

    Theoretically it should check the variable $action, which can be of any values that retrieves mysql data such as row, array, assoc, object. I just looked at mysqli's manual and found that there are still many more possible ways to fetch data. I want to use a protected method called fetch(), which also accepts the variable $action and returns results from such as mysqli->fetch_array() and mysqli->fetch_object(). If works, the script should look like this one below:

     

      public function select($action = ""){
        if(empty($this->column)) $this->column = "*";
        $query = "SELECT {$this->column} FROM {$this->table}";
    $query .= (!empty($this->where))?" WHERE {$this->where}":"";
    $query .= (!empty($this->order))?" ORDER BY {$this->order}":"";
    $query .= (!empty($this->limit))?" LIMIT {$this->limit}":"";
        echo $query."<br>";
        $this->result = $this->mysqli->query($query);
        $result = $this->result->fetch($action)
        $this->reset();
        return $result;
      }
    
    protected function fetch($action){
       switch($action){
         case "row":
         // fetch data using mysqli->fetch_row()
         case "assoc":
         // fetch data using mysqli->fetch_assoc()
         case "array":
         // fetch data using mysqli->fetch_array()
         case "object":
         // fetch data using mysqli->fetch_object()
         case "num":
         // returns the number of rows...
         ...
         default:
         // returns nothing
       }
      
    }
    

     

    How can I design such a protected method so that it can be accessed within the select() method and other possible future methods I write(such as mselect(), which is used to select data from more than one table)? Please help.

  6. Well I tried to extend the class mysqli with its inheritance called Database, which can retrieve database info easily(in one line if done correctly). It does not work out so far, as I am getting the following errors:

     

    Here is the Database Class as defined:

    class Database extends mysqli{
      private $select, $create, $insert, $alter, $update, $delete, $drop;
      protected $mysql, $result, $table, $column, $where, $value, $limit, $order, $type;
    
      public function __construct($host, $user, $pass, $db){
        $this->mysql = new mysqli($host, $user, $pass, $db) 
    	   or die("Error connecting to the database {$db}");
    
      }
    
      public function __destruct(){
    $this->mysql->close();
      }
    
      protected function prepareQuery(){
    if ($prepare = $this->mysqli->prepare($this->query)) {
      trigger_error("Problem preparing query ($this->query) ".$this->mysqli->error, E_USER_ERROR);
    }
    return $prepare;
      }
      
      protected function reset(){
    unset($this->table);
    unset($this->column);
    unset($this->where);
    unset($this->value);
    unset($this->limit);
    unset($this->order);
      }
    
      public function select($column){    
        $this->select = implode(",", $column);
    return $this;
      }
      
      public function table($table){
        $this->table = $table;
    return $this;
      }
      
      public function where($where, $comparison = "=", $logic){
        $i = 0;
        foreach ($where as $col => $val){
      $wherestring .= (is_array($comparison)) ? " {$col} {$comparison[$i]} '{$val}'" : " WHERE {$col} {$comparison} '{$val}'";
      $wherestring .= ($i < (count($where)-1))?" {$logic[$i]}" :" ";
      $i++;
    }
    $this->where = $wherestring;
    return $this;
      }
      
      public function limit($limit){
        $this->limit = $limit;
    return $this;
      }
      
      public function order($order){
        $this->order = $order;
    return $this;
      }
      
      public function runquery($method){
        $query = "{$method} {$this->select} FROM {$this->table}";
    if(!empty($this->where)) $query .= " WHERE {$this->where}";
    if(!empty($this->limit)) $query .= " LIMIT {$this->limit}";
    if(!empty($this->order)) $query .= " ORDER BY {$this->order}";
    echo "The generated Query is: \n".$query;
        $this->result = parent::query($query);
        $result = parent::fetch_array($this->result);
    return $result;
      } 
    
    }
    

     

    And this is the way I run it from a script file:

    include("inc/config.php");
    include("classes/class_data.php");
    
    $db = new Database($dbhost, $dbuser, $dbpass, $dbname);
    $row = $db->select(array("password","email"))->table($prefix."users")->where(array("uid"=>1, "username"=>Admin"),array("=","="),array("AND"))->limit(2)->order("uid")->runquery("SELECT");
    

     

    It did not work, and I got the following warning and error messages:

    Warning: mysqli::query() [mysqli.query]: Couldn't fetch Database in classes/class_data.php on line 70
    Fatal error: Call to undefined method mysqli::fetch_array() inclass_data.php on line 71
    
    

     

    I am a bit confused now since I cant seem to figure out a way to resolve this problem. Can anyone of you please help? Id appreciate it very much.

  7. Well I am trying to design a class called database, which will significantly reduces the amount of codes/lines running mysql query in a script file. The object methods are basically mysql operations such as create(), select(), update(), insert(), delete() and so on. I have two possible approaches to execute mysql queries, and lemme illustrate point with the 'select from table' method:

     

    Approach 1: Write everything inside a gigantic method, such as select()

     

    class Database{
       // codes
       public function select($table, $columns, $index, $where, $comparison, $logic, $returntype, $extra){
      // codes to return a highly customized query string, then execute this query, and finally returns any type as specified in $returntype(field, string, row, assoc, array or object)
      // the codes are extremely long here...
      } 
      // more codes
    }
    
    // to return an array, for instance, the following line may be written to retrieve database info:
    $db = new Database($databasehost, $userName, $userPassword, $databaseName);
    $array = $db->select("users", array("password", "email"), true, array("id" => 1, "username" => "admin"), "=", "AND","ARRAY", "LIMIT = 1"); 
    
    

     

    Approach 2: Use Object Method Chaining

    class Database{
      private $method, $table, $column, $where, $comparison, $logic, $limit, $returntype;
      public function select($column == "*"){
      // simple codes here
      }
      public function table($table){
      // simple codes here
      }
      public function where($where){
      // simple codes here
      }
      public function comparison($comparison){
      // simple codes here
      }
      public function logic($logic){
      // simple codes here
      }
      public function limit($limit){
      // simple codes here
      }
      public function result($method){
      // execute the query and is ready to fetch
      }
      public function fetch($returntype){
      // fetch rows, assoc, array, objects or else based on return type
      }
    }
      
    // to return an array, for instance, we execute multiple methods altogether:
    $db = new Database($databasehost, $userName, $userPassword, $databaseName);
    $array = $db->select(array("password", "email"))->table("user")->where(array("id" => 1, "username" => "admin" )) -> comparison("=") -> logic("AND") => limit(1) -> result() -> fetch("ARRAY");
    
    

     

    Both approaches are likely to work on my site, but I do not know which one is considered more professional and which one runs better performance-wise. The first approach is quite complicated to use for another programmer, but it may be more efficient. The second approach is more readable and flexible, while I wonder if running a chain of object methods will consume a huge amount of CPU and bandwidth. Can anyone of you please gimme your points of view on this? Thank you so much.

  8. Well I have a library file class_database.php which defines a class called 'database' and a method called 'get' to retrieve database info. It was originally designed to return a two-dimensional array with the format of $array['index']['associative']. Right now I want to change this so as to return a result, which can then be used in other script files to retrieve data by using the fetch_array() method after getting this result. It doesnt work though, and I got this error 'Call to undefined method mysqli_stmt::get_result()', which confuses me...

     

    The two methods get() and _buildQuery are shown below, please help me figure out how to return an Mysql result so that I can use while($row = $db->get()->fetch_array()) on it with flexibility...

     

    The method get()

    public function get($tableName, $numRows = NULL) 
    {
    
    	$this->_query = "SELECT * FROM $tableName";
    	$stmt = $this->_buildQuery($numRows);
    	$stmt->execute();
                    $results = $stmt->get_result();
    
    	$this->reset();
    	return $results;
    }
    

     

    The method  _buildQuery is shown below:

    protected function _buildQuery($numRows = NULL, $tableData = NULL) 
    {
    	(gettype($tableData) === 'array') ? $hasTableData = true : $hasTableData = false;	
    	(!empty($this->_where )) ? $hasConditional = true : $hasConditional = false;
    
    	// Did the user call the "where" method?
    	if (!empty($this->_where)) {
    
    		// if update data was passed, filter through and create the SQL query, accordingly.
    		if ($hasTableData) {
    			$i = 1;
    			$pos = strpos($this->_query, 'UPDATE');
    			if ( $pos !== false) {
    				foreach ($tableData as $prop => $value) {
    					// determines what data type the item is, for binding purposes.
    					$this->_paramTypeList .= $this->_determineType($value);
    
    					// prepares the reset of the SQL query.
    					($i === count($tableData)) ?
    						$this->_query .= $prop . ' = ?':
    						$this->_query .= $prop . ' = ?, ';
    
    					$i++;
    				}
    			}
    		}
    
    		//Prepair the where portion of the query
    		$this->_query .= ' WHERE ';	
    		$i = 1;
    		foreach ($this->_where as $column => $value) {
    			// Determines what data type the where column is, for binding purposes.
    			$this->_whereTypeList .= $this->_determineType($value);
    
    			// Prepares the reset of the SQL query.
    			($i === count($this->_where)) ?
    				$this->_query .= $column . ' = ?':
    				$this->_query .= $column . ' = ? AND ';
    
    			$i++;
    		}
    
    	}
    
    	// Determine if is INSERT query
    	if ($hasTableData) {
    		$pos = strpos($this->_query, 'INSERT');
    
    		if ($pos !== false) {
    			//is insert statement
    			$keys = array_keys($tableData);
    			$values = array_values($tableData);
    			$num = count($keys);
    
    			// wrap values in quotes
    			foreach ($values as $key => $val) {
    				$values[$key] = "'{$val}'";
    				$this->_paramTypeList .= $this->_determineType($val);
    			}
    
    			$this->_query .= '(' . implode($keys, ', ') . ')';
    			$this->_query .= ' VALUES(';
    			while ($num !== 0) {
    				($num !== 1) ? $this->_query .= '?, ' : $this->_query .= '?)';
    				$num--;
    			}
    		}
    	}
    
    	// Did the user set a limit
    	if (isset($numRows)) {
    		$this->_query .= " LIMIT " . (int) $numRows;
    	}
    
    	// Prepare query
    	$stmt = $this->_prepareQuery();
    
    	// Prepare table data bind parameters
    	if ($hasTableData) {
    		$this->_bindParams[0] = $this->_paramTypeList;
    		foreach ($tableData as $prop => $val) {
    			array_push($this->_bindParams, &$tableData[$prop]);
    		}
    	}
    	// Prepare where condition bind parameters
    	if($hasConditional) {
    		if ($this->_where) {
    			$this->_bindParams[0] .= $this->_whereTypeList;
    			foreach ($this->_where as $prop => $val) {
    				array_push($this->_bindParams, &$this->_where[$prop]);
    			}
    		}	
    	}
    	// Bind parameters to statment
    	if ($hasTableData || $hasConditional){
    		call_user_func_array(array($stmt, 'bind_param'), $this->_bindParams);
    	}
    
    	return $stmt;
    }
    

  9. Well lately I've decided to split the big script in admin.php(admin control panel file) into several smaller script files such as admin_index.php, admin_settings.php and admin_createuser.php. I was thinking about this idea of locating all menus/submenus to the left hand side of the page and use an iframe to load info from any admin script files. This way the admin can access everything without having to be directed to a different url. I believe this is what Vbulletin has been doing for its ACP(they may have used javascript though), and I have a few questions to ask:

     

    1. Is this a feasible idea, especially if I choose not to use javascript?

    2. Is it safe to design admin control panel this way for a PHP script? If not, please lemme know possible security issues?

    3. Is it possible to restrict direct access to other admin type script files, but allow access if they are loaded in iframe?

     

    Please do lemme know, thanks.

  10. Well I tried to create three sample tabs but I cannot seem to find a way to fit them in the template I use on my site. Can anyone of you please help? The files sample.php and the included file tabs.php are shown below:

     

    sample.php: The one that displays tabs:

    <?php
    
    include("inc/functions.php");
    require_once("tabs.php");
    
    //***************//
    //  START SCRIPT //
    //***************//
    tabs_header(); 
    tabs_start(); 
    tab("Tab One");
    echo "This is the first tab.";
    tab("Tab Two"); 
    echo "This is the second tab.";
    tab("Tab Three");
    echo "This is the third tab.";
    tabs_end();
    
    echo showpage($article_title, $article_content, $date);
    
    ?>
    

     

    tabs.php: The tabs function file

    <?php
    
    $tabs = array();
    
    function tabs_header()
    {
    ?>
    <style type = "text/css">
    .tab{
        border-bottom:1px solid black;
        text-align: center;
        font-family: arial, verdana;
    }
    .tab-active{
        border-left: 1px solid black;
        border-top: 1px solid black;
        border-right: 1px solid black;
        text-align: center;
        font-family: arial, verdana;
        font-weight: bold;
    } 
    .tab-content{
        padding: 5px;
        border-left: 1px solid black;
        border-right: 1px solid black;
        border-bottom: 1px solid black;
    }
    </style>
    <?php
    }
    
    function tabs_start(){
      ob_start();
    }
    
    function endtab(){
      global $tabs;
      $text = ob_get_clean();
      $tabs[count($tabs) - 1]['text'] = $text;
      ob_start();
    }
    
    function tab($title){
      global $tabs;
      if(count($tabs)>0)
      endtab();
      $tabs[] = array(
                 title => $title,
                 text => ""
                );
    }      
    
    function tabs_end(){
      global $tabs;
      endtab();
      ob_end_clean();
      $index = 0;
      if($_GET['tabindex'])
        $index = $_GET['tabindex'];
        
    ?>
    
    <table width = "100%" cellspacing = "0" cellpadding = "0">
    <tr>
    
    <?php 
      $baseuri = $_SERVER['REQUEST_URI'];
      $baseuri = preg_replace("/\?.*$/", "", $baseuri);
      $curindex = 0;
      foreach($tabs as $tab){
        $class = "tab";
        if($index == $curindex)
          $class = "tab-active";
    ?>
    
    <td class = "<?php echo($class); ?>">
    <a href="<?php echo($baseuri."?tabindex=".$curindex);?>">
    <?php echo($tab['title']); ?>
    </a>
    </td>
    
    <?php 
      $curindex +=1;
      }
    ?>
    
    </tr>
    <tr><td class = "tab-content" colspan="<?php echo(count($tabs) + 1); ?>">
    <?php echo($tabs[$index]['text']); ?>
    </td></tr>
    </table>
    <?php
    }
    ?>     
    

     

    The showpage function is used to load page title, text and theme, not sure if I should post this too... Incase you wonder, the sample.php is somewhat messed up as the tabs aint shown in the content section as they are supposed to:

    x41ago.jpg

     

  11. Well here are some examples:

     

    $query = "SELECT * FROM {$prefix}items WHERE itemname = '{$itemname}'";
    $result = mysql_query($query);
    $row = mysql_fetch_array($result);
    

     

    The above code uses three lines to retrieve database info from a table and sent it to an array called $row for future use. It may look fine with only one query being run, but it can be rather annoying if I have to write 2 or 3+ times of such code over and over again, especially in the script file of admin control panel. Similarly, the one below updates database info, and I believe it can be simplified.

     

    mysql_query("UPDATE {$prefix}items SET category='{$category}' , 
                                                                   itemname='{$itemname}' , 
    						       shop='{$shop}' , 
    						       price='{$price}' ,                   
    						       consumable='{$consumable}' WHERE id='{$id}'");		
    

  12. Well actually I do need a more efficient and convenient way to select/insert/update database info. Some of my script files has tens of lines of "SELECT from db.tablename where columname = '$name'". It is getting quite tedious and annoying, it would be nice if you could provide me with an easier approach with or w/o OOP.

  13. I see, this makes perfect sense to me. It seems that you have a select function in it, and it is quite flexible to use. Do you also have update and delete functions for the class database? From my experience, its quite annoyingly tedious to write multiple lines of mysql query commands in a PHP codes.

  14. I see, that makes sense. I should write an inheritance class like this then?

     

    Class mysqli_extra extends mysqli{
      var $prefix;
    // more lines of codes in this child class, the prefix name can be retrieved from config file.
    }
    

     

    Also a question that seems irrelevant to this topic. Why dont you use mysql_fetch_object in the OOP approach? Is it because there is no easy way to iterate an object like what we can normally do with an array(by using foreach).

     

  15. I see, thanks again. I wonder if the class mysqli can identify a table's prefix though, as I browsed through the manual of mysqli class from php.net. It seems that the four arguments passed into mysqli class are 'hostname', 'username', 'password', 'database', what should I do with database tables with a prefix?

  16. This is detailed enough, thank you so much. And yeah I do understand basic class structure, just never got it to work with mysql since I learned PHP classes/objects from books that do not introduce Mysql together with OOP.

  17. Thanks a lot, this looks like a powerful script indeed. Would you mind adding a few comments in your code explaining how a random number is generated and how the script determines if the condition matches for a certain instance(such as black or white color)? Also what if the data for object's name and probability properties are retrieved from a mysql table's two columns called 'name', 'probability'? I am fine with OOP, but I dunno how to write OOP code together with Mysql integration.

  18. Well I was trying to design a random encounter event system, but got myself into a big issue with PHP random number generator(rand or mt_rand). A simple code for how these functions work is:

     

    $num = mt_rand(0,15)
    if($num < 5){
    // codes to execute
    }
    else{
    // codes to execute
    }
    

     

    The codes look nice, but it becomes a problem when multiple events with certain probability to occur need to be programmed. Consider there are 5 colors to select for a new automobile(black, while, yellow, red and blue), the probability for each of the color to be chosen is (30%, 30%, 20%, 10%, 10%), how am I supposed to write such a script in PHP efficiently? I know its possible to do it like this, but...

    $num = mt_rand(0,99)
    if($num < 30){
    $color = "black";
    }
    else if($num >= 30 and $num <60 ){
    $color = "white";
    }
    else if($num >= 60 and $num <80 ){
    $color = "yellow";
    }
    else if($num >= 80 and $num <90 ){
    $color = "red";
    }
    else{
    $color = "blue";
    }
    

     

    See the problem with this script? Yes, it is long and tedious, and more importantly inflexible. For a PHP random encounter script, the user may not know how many random events can occur(except for the fact that their probability values do add up to 1). It is also a common practice to retrieve random event names, probabilities and other properties from mysql with mysql_fetch_array() and loop. I do not know how to write such a program at this moment, can anyone of you please give a try and lemme know there is a way to handle multiple random events with different probability to occur easily? Thanks.

     

  19. I see, thanks for your reply and sorry for the confusion. The idea here is that it is quite tedious to always write Mysql codes to retrieve a certain set of data again and again, this was why $GLOBALS was registered in the first place. Again please allow me to show you an example:

     

    Without registering $GLOBALS, the following lines have to be written whenever the script needs to retrieve data from mysql table:

     

    $result = mysql_query( "SELECT * FROM {$prefix}users WHERE uid = '$uid'");
    $row = mysql_fetch_array($result);
    $money = $row['money'];
    

     

    It may not look tedious for this time being, but it can be annoying if you have to write the same code over and over again and in different script files. With registering $GLOBALS, its possible to retrieve information simply by writing $GLOBALS['money']. This act makes retrieving and updating database info much easier, and it is why I am hesitant what to do with registered $GLOBALS.

  20. Well I heard that registering $GLOBALS is a bad practice in general since their values can be changed by anyone at anytime. However, the usage of $GLOBALS does simplify the script considerably at times when a certain column in a table needs to be retrieved repeatedly. A good example is user's money data stored in table prefix_users as shown below:

     

    $result = mysql_query( "SELECT * FROM {$prefix}users WHERE uid = '$uid'");
    $GLOBALS['usersettings'] = mysql_fetch_array($result);
    $GLOBALS['money'] = $GLOBALS['usersettings']['money']; 
    

     

    If the above code is included in a function file, it will be possible to simply use $GLOBALS['money'] to retrieve user's money data without having to write lines of mysql commands everytime. So I was wondering, is there another way to retrieve database info from a certain column easily but not to register $GLOBALS? Just curious. 

  21. What's wrong with using $_POST['variables'] directly in your code? They are perfectly fine variables.

     

    If you want an $item array that is a copy of the $_POST array -

    $item = $_POST;

     

    If you want to populate scaler program variables from the $_POST elements, you can use extract  Use EXTR_PREFIX_ALL as the second parameter and use a unique prefix to insure that hackers cannot overwrite any of your existing program variables.

     

    Thanks a lot, I will give a try using extract($_POST, EXTR_PREFIX_ALL, 'item_'). Some people said extract() has security issues though...

     

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.