I have 2 methods, that are pretty much exactly the same and I'd likie someone to help me refactor them:
public static function searchFromVideoRequest($word, $returnPropelObjects = false)
{
$c = new Criteria();
$c->addJoin(YoutubeVideoPeer::ID,ItemPeer::YOUTUBE_VIDEO_ID);
$c->addSelectColumn(self::TITLE);
$c->addSelectColumn(self::ID);
$c->add(ItemPeer::TITLE, '%'.$word.'%', Criteria::LIKE);
$c->addAnd(self::YOUTUBE_VIDEO_ID, null, Criteria::ISNOTNULL);
$c->addAscendingOrderByColumn(self::TITLE);
if ($returnPropelObjects)
return self::doSelect($c);
$stmt = self::doSelectStmt($c);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return $results;
}
public static function searchFromFlickrRequest($word, $returnPropelObjects = false)
{
$c = new Criteria();
$c->addJoin(FlickrPhotoPeer::ID,ItemPeer::FLICKR_PHOTO_ID);
$c->addSelectColumn(self::TITLE);
$c->addSelectColumn(self::ID);
$c->add(ItemPeer::TITLE, '%'.$word.'%', Criteria::LIKE);
$c->addAnd(self::FLICKR_PHOTO_ID, null, Criteria::ISNOTNULL);
$c->addAscendingOrderByColumn(self::TITLE);
if ($returnPropelObjects)
return self::doSelect($c);
$stmt = self::doSelectStmt($c);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return $results;
}
Thanks
To refactor such methods you can split up them into a few methods that will contain common code and make them private, so no one can use them outside the class:
public static function searchFromVideoRequest($word, $returnPropelObjects = false)
{
$c = self::buildSearchCriteria($word);
$c->addJoin(YoutubeVideoPeer::ID,ItemPeer::YOUTUBE_VIDEO_ID);
$c->addAnd(self::YOUTUBE_VIDEO_ID, null, Criteria::ISNOTNULL);
return self::getSearchResult($c, $returnPropelObjects);
}
public static function searchFromFlickrRequest($word, $returnPropelObjects = false)
{
$c = self::buildSearchCriteria($word);
$c->addJoin(FlickrPhotoPeer::ID,ItemPeer::FLICKR_PHOTO_ID);
$c->addAnd(self::FLICKR_PHOTO_ID, null, Criteria::ISNOTNULL);
return self::getSearchResult($c, $returnPropelObjects);
}
private static function buildSearchCriteria($word)
{
$c = new Criteria();
$c->addSelectColumn(self::TITLE);
$c->addSelectColumn(self::ID);
$c->add(ItemPeer::TITLE, '%'.$word.'%', Criteria::LIKE);
$c->addAscendingOrderByColumn(self::TITLE);
return $c;
}
private static function getSearchResult($c, $returnPropelObjects)
{
if ($returnPropelObjects)
return self::doSelect($c);
$stmt = self::doSelectStmt($c);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return $results;
}
PS: And I think the question is OK.
Related
I have a db class that I've been using for years. I noticed something interesting today.
function example_function($key)
{
global $db; // db variable - class
$a_id = 1; // example
$admins = $db->table('admins')->where('id','=',$a_id)->order('id','desc')->limit(1)->get();
$admin_data = $admins['data'][0];
$return = $admin_data[$key];
return $return;
}
$id = example_function('id');
$new = $db->table('rooms')->where('id','=',$id)->order('id','desc')->limit(2)->get();
print_r($new);
//WORKS
$new = $db->table('rooms')->where('id','=',2)->order('id','desc')->limit(2)->get();
print_r($new);
//WORKS
$new = $db->table('rooms')->where('id','=',example_function('id'))->order('id','desc')->limit(2)->get();
print_r($new);
//NOT WORKING ?
->where('id','=',example_function('id'))->
When I use an external function in this part, things get messy.
But the following also works. When doing another operation with the db in the relevant function, things get messy.
function example_function($key)
{
return '1';
}
$new = $db->table('rooms')->where('id','=',example_function('id'))->order('id','desc')->limit(2)->get();
Is the problem in global usage? Or is the database class wrong?
DB CLASS
class DB
{
protected $connect;
protected $db_database = DB_DATABASE;
protected $db_host = DB_HOST;
protected $db_username = DB_USERNAME;
protected $db_password = DB_PASSWORD;
protected $db_name = DB_NAME;
protected $db_prefix = DB_PREFIX;
//parameters
protected $error = null;
protected $last_id = null;
protected $query = null;
protected $from = null;
protected $select = '*';
protected $where = null;
protected $group = null;
protected $order = null;
protected $limit = null;
protected $pagination_type = false;
protected $per_page = 0;
protected $get_arr = null;
function __construct()
{
try {
$this->connect = new PDO("{$this->db_database}:host={$this->db_host};dbname={$this->db_name};charset=utf8mb4", "{$this->db_username}", "{$this->db_password}");
$this->connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connect->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8mb4");
} catch ( PDOException $e ){
echo "<b>Veritabanı bağlantısı sağlanamadı! - Hata Kodu: </b>".$e->getMessage();
exit;
}
}
public function now($type="datetime")
{
switch($type)
{
case 'timestamp';
return time();
case 'date';
return date('-m-d');
case 'datetime';
return date('Y-m-d H:i:s');
default:
return date('Y-m-d H:i:s');
}
}
public function m_empty($data)
{
if($data=='' and $data!='0')
{
return true;
}
else
{
return false;
}
}
public function query($query,$arr=false)
{
$this->reset();
if($query!="")
{
try
{
$run = $this->connect->prepare($query);
if($arr)
{
if(is_array($arr))
{
$run->execute($arr);
return $run;
}
else
{
$run->execute(array($arr));
return $run;
}
}
else
{
$run->execute();
return $run;
}
} catch (PDOException $e) {
$this->error = $e->getMessage();
return false;
}
}
return false;
}
public function table($table)
{
$this->from = $this->db_prefix . $table;
return $this;
}
public function select($fields)
{
$this->select = $fields;
return $this;
}
public function where($field,$op='=',$values,$and="AND")
{
if(!$this->m_empty($field))
{
if(is_null($this->where))
{
$this->where="{$field} {$op} ?";
$this->get_arr[] = $values;
}
else
{
$this->where.=" {$and} {$field} {$op} ?";
$this->get_arr[] = $values;
}
}
return $this;
}
public function where_set($field,$op='=',$values,$and="AND")
{
if(!$this->m_empty($field) and !$this->m_empty($values))
{
if(is_null($this->where))
{
$this->where="{$field} {$op} {$values}";
}
else
{
$this->where.=" {$and} {$field} {$op} {$values}";
}
}
return $this;
}
public function group($fields)
{
if(is_null($this->group))
{
$this->group = $fields;
}
else
{
$this->group .=",{$fields}";
}
return $this;
}
public function order($field,$type="desc")
{
if(!is_null($field))
{
if(is_null($this->order))
{
if(strtolower($field)=="rand()")
{
$this->order = $field;
}
else
{
$this->order = $field.' '.strtoupper($type);
}
}
else
{
if(strtolower($field)=="rand()")
{
$this->order .=",{$fields}";
}
else
{
$this->order .= ','.$field.' '.strtoupper($type);
}
}
}
return $this;
}
public function limit($start,$end=null)
{
if(is_null($end))
{
if(is_numeric($start))
{
$this->limit = $start;
}
}
else
{
if(is_numeric($start) and is_numeric($end))
{
$this->limit = "{$start},{$end}";
}
}
return $this;
}
public function pagination($per_page)
{
if(is_numeric($per_page))
{
$this->per_page = $per_page;
$this->pagination_type = true;
}
return $this;
}
public function get()
{
$query = "SELECT {$this->select} FROM {$this->from}";
if(!is_null($this->where))
{
$query.=" where {$this->where}";
}
if(!is_null($this->group))
{
$query.=" group by {$this->group}";
}
if(!is_null($this->order))
{
$query.=" order by {$this->order}";
}
if($this->pagination_type)
{
$c_per_page = $this->per_page;
$c_arr = $this->get_arr;
$extra_query = preg_replace("#SELECT (.*?) FROM#","SELECT COUNT(*) as total_count FROM",$query);
$all = $this->query($extra_query,$this->get_arr);
if($all)
{
$total_count = $all->fetchAll(PDO::FETCH_ASSOC)[0]['total_count'];
$page_count = ceil($total_count/$c_per_page);
$current_page = (integer)m_u_g(DB_PAGINATION_GET) ? (integer)m_u_g(DB_PAGINATION_GET) : 1;
$current_limit=($current_page - 1) * $c_per_page;
$query = $query." limit {$current_limit},{$c_per_page}";
$current_rows = $this->query($query,$c_arr);
$data = $current_rows->fetchAll(PDO::FETCH_ASSOC);
$return = array();
$return['total_count'] = $total_count;
$return['current_count'] = count($data);
$return['total_page'] = $page_count;
$return['current_page'] = $current_page;
$return['data'] = $data;
return $return;
}
else
{
return false;
}
}
else
{
if(!is_null($this->limit))
{
$query.=" limit {$this->limit}";
}
$gets = $this->query($query,$this->get_arr);
if($gets)
{
$data = $gets->fetchAll(PDO::FETCH_ASSOC);
$return = array();
$return["total_count"] = count($data);
$return["data"] = $data;
return $return;
}
else
{
return false;
}
}
}
public function get_var($field)
{
if($this->m_empty($field))
{
return false;
}
else
{
$query = "SELECT {$field} FROM {$this->from}";
if(!is_null($this->where))
{
$query.=" where {$this->where}";
}
if(!is_null($this->order))
{
$query.=" order by id desc limit 1";
}
$gets = $this->query($query,$this->get_arr);
if($gets)
{
return $gets->fetchAll(PDO::FETCH_ASSOC)[0][$field];
}
else
{
return false;
}
}
}
public function get_vars($table,$where,$var,$type=true)
{
if($type)
{
$data = $this->connect->query("select $var from $table where $where order by id desc limit 1")->fetch(PDO::FETCH_ASSOC);
}
else
{
$data = $this->connect->query("select $var from $table where $where")->fetch(PDO::FETCH_ASSOC);
}
return $data["$var"];
}
public function count()
{
$grouped = false;
$query = "SELECT count(*) as total_count FROM {$this->from}";
if(!is_null($this->where))
{
$query.=" where {$this->where}";
}
if(!is_null($this->group))
{
$grouped = true;
$query.=" group by {$this->group}";
}
if(!is_null($this->order))
{
$query.=" order by {$this->order}";
}
$gets = $this->query($query,$this->get_arr);
if($gets)
{
if($grouped)
{
$count = 0;
foreach($gets->fetchAll(PDO::FETCH_ASSOC) as $counts)
{
$count = $count+$counts["total_count"];
}
return $count;
}
else
{
return $gets->fetch(PDO::FETCH_ASSOC)["total_count"];
}
}
else
{
return false;
}
}
public function insert(array $data)
{
if(is_array($data))
{
$query = 'INSERT INTO '.$this->from;
$keys = array_keys($data);
$query.=' ('.implode(',',$keys).') values (';
$query_add='';
$values = array_values($data);
foreach($values as $val)
{
$query_add.='?,';
}
$query_add = trim($query_add,',');
$query.=$query_add.')';
if($this->query($query,$values))
{
$this->last_id = $this->connect->lastInsertId();
return $this->last_id;
}
else
{
return false;
}
}
return false;
}
public function update(array $data)
{
if(is_array($data))
{
$query = "UPDATE {$this->from} set";
$keys = array_keys($data);
$values = array_values($data);
$query_add = '';
foreach($keys as $key)
{
$query_add.=" {$key} = ?,";
}
$query_add = trim($query_add,',');
$query.=$query_add;
if(!is_null($this->where))
{
$query.=" where {$this->where}";
}
$new = array_merge($values,$this->get_arr);
if($this->query($query,$new))
{
return true;
}
else
{
return false;
}
}
return false;
}
public function delete()
{
$query = "DELETE FROM {$this->from}";
if(!is_null($this->where))
{
$query.=" where {$this->where}";
}
if($this->query($query,$this->get_arr))
{
return true;
}
else
{
return false;
}
}
public function error()
{
return $this->error;
}
public function last_id()
{
return $this->last_id;
}
protected function reset()
{
$this->error = null;
$this->last_id = null;
$this->query = null;
$this->from = null;
$this->select = '*';
$this->where = null;
$this->group = null;
$this->order = null;
$this->limit = null;
$this->pagination_type = false;
$this->per_page = 0;
$this->get_arr = null;
}
}
$db = new DB();
?>```
The issue is caused by changing the mutable object properties prior to completing the desired query with Db::get(). Resulting in the Db::$table property being changed when being called on the same instance of the Db class.
This is one of the reasons behind best-practices discouraging the use of global, since the intention/context of the current variable state is not easily determined.
What's happening with your code is
Db::$table = 'rooms'
Db::$table = 'admin'
Db::$where = 'admin.id = 1'
Db::get() //SELECT * FROM admin WHERE admin.id = 1
Db::$table = null
Db::$where = null
Db::$where = 'rooms.id = 1'
Db::get() //SELECT * FROM WHERE rooms.id = 1
To avoid the issue and ensure the desired order of operations, you need to call Db::get() prior to calling any other DB methods that modify the properties of the query issued when calling DB::get().
$roomId = example_function('id'); // (int) 1
//SELECT * FROM admin WHERE id = 1
$db->table('rooms')->where('id','=', $roomId)->get();
//SELECT * FROM rooms WHERE id = 1
Alternatively, to ensure that the intention of two individual queries is preserved, you would need to create a separate instance of DB for your second query. However, this would also create a separate PDO instance with your current code.
To avoid a second instance of PDO you would have to change $this->connect to a static property self::$connect and refactor any method using $this->connect to self::$connect. The static property will ensure that only a single instance of PDO will ever exist whenever new Db() is called.
class Db
{
protected static $connect;
//...
public function __construct()
{
try {
if (!isset(self::$connect)) {
self::$connect = new PDO("{$this->db_database}:host={$this->db_host};dbname={$this->db_name};charset=utf8mb4", "{$this->db_username}", "{$this->db_password}");
self::$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$connect->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8mb4");
}
} catch ( PDOException $e ){
echo "<b>Veritabanı bağlantısı sağlanamadı! - Hata Kodu: </b>".$e->getMessage();
exit;
}
}
//...
}
Afterwards replace all usages of global $db; in your application with $db = new Db();.
This approach will also ensure your entire codebase is protected from the mutable object property overwrite issue and better adheres to best-practices.
function example_function($key)
{
$db = new Db();
$a_id = 1; // example
$admins = $db->table('admins')->where('id','=',$a_id)->order('id','desc')->limit(1)->get();
$admin_data = $admins['data'][0];
$return = $admin_data[$key];
return $return;
}
$new = $db->table('rooms')->where('id','=', example_function('id'))->get();
Another approach could be to use clone to workaround the mutable object issue. However, using clone will have adverse affects on the PDO instance, since it resides in the Db class. Most likely requiring you to separate the PDO connection code from the Query Builder code.
function example_function($key)
{
global $db;
$db2 = clone $db;
$a_id = 1; // example
$admins = $db2->table('admins')->where('id','=',$a_id)->order('id','desc')->limit(1)->get();
//...
}
I have a PHP class that is meant to get a mysqli query, make a multidimensional array, and currently just echo the whole array. It is this code:
include("connect.php");
class database
{
public $motto;
public $motto_array = array();
public $rating;
public $rating_array = array();
public $category;
public $score;
private $mysqli;
public $counter_array = array();
public $multi_dim_values = array();
public $multi_dim_category = array();
function setMysqli($mysqli)
{
$this->mysqli = $mysqli;
}
function setCategory($category)
{
$this->category = $category;
}
function query_category()
{
if ($stmt = $this->mysqli->prepare("SELECT motto, score FROM mottos WHERE category=? ORDER BY score DESC"))
{
$stmt->bind_param("s", $this->category);
$stmt->execute();
$stmt->bind_result($motto, $ranking);
while ( $stmt->fetch() ) {
$this->motto_array[] = $motto;
$this->rating_array[] = $ranking;
}
$stmt->close();
}
}
function multi_dim_array()
{
$multi_dim_values = array($this->motto_array, $this->rating_array);
$counter_array = range(0,count($this->motto_array)-1);
foreach($counter_array as $index => $key) {
$foreach_array = array();
foreach($multi_dim_values as $value) {
$foreach_array[] = $value[$index];
}
$multi_dim_category[$key] = $foreach_array;
}
return $multi_dim_category;
}
}
$class = new database;
$class->SetMysqli($mysqli);
$class->SetCategory("person");
$class->query_category();
print_r($class->multi_dim_array);
print_r($class->multi_dim_category);
connect.php has the database connection information for the mysqli.
I am learning OOP, so I did this in procedural, and it works fine, with this code:
include("connect.php");
function category($mysqli, $cat)
{
if ($stmt = $mysqli->prepare("SELECT motto, score FROM mottos WHERE category=? ORDER BY score DESC"))
{
$stmt->bind_param("s", $cat);
$stmt->execute();
while($stmt->fetch())
{
printf ("[%s (%s) in %s] \n", $motto, $ranking, $category);
$array .= compact("motto", "category", "ranking");
}
print_r($array);*/
$a = array();
$b = array();
$c = array();
$stmt->bind_result($motto, $ranking);
while ( $stmt->fetch() ) {
$a[] = $motto;
$b[] = $ranking;
}
$result = array();
$values = array($a, $b);
$c = range(0,count($a)-1);
foreach($c as $index => $key) {
$t = array();
foreach($values as $value) {
$t[] = $value[$index];
}
$result[$key] = $t;
}
return $result;
$stmt->close();
}
}
$cat = "person";
$array_one = category($mysqli, $cat);
print_r($array_one);
This prints the multidimensional array just like I want it to.
What am I doing wrong in the OOP code?
Thank you.
Your code:
print_r($class->multi_dim_array);
You forgot the (), so you're not invoking the method. You're accessing a (non-existent) property. Try this:
print_r($class->multi_dim_array());
I'm using this database MySQLi wrapper:
Class dbWrapper {
protected $_mysqli;
protected $_debug;
public function __construct($host, $username, $password, $database, $debug) {
$this->_mysqli = new mysqli($host, $username, $password, $database);
$this->_mysqli->set_charset("utf8");
$this->_debug = (bool) $debug;
if (mysqli_connect_errno()) {
if ($this->_debug) {
echo mysqli_connect_error();
debug_print_backtrace();
}
return false;
}
return true;
}
public function q($query) {
if ($query = $this->_mysqli->prepare($query)) {
if (func_num_args() > 1) {
$x = func_get_args();
$args = array_merge(array(func_get_arg(1)),
array_slice($x, 2));
$args_ref = array();
foreach($args as $k => &$arg) {
$args_ref[$k] = &$arg;
}
call_user_func_array(array($query, 'bind_param'), $args_ref);
}
$query->execute();
if ($query->errno) {
if ($this->_debug) {
echo mysqli_error($this->_mysqli);
debug_print_backtrace();
}
return false;
}
if ($query->affected_rows > -1) {
return $query->affected_rows;
}
$params = array();
$meta = $query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($query, 'bind_result'), $params);
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
} else {
if ($this->_debug) {
echo $this->_mysqli->error;
debug_print_backtrace();
}
return false;
}
}
public function handle() {
return $this->_mysqli;
}
}
But when I make a query, for example SELECT This FROM Database, and I want to display the result, I have to echo $result[0]['This']. Why that? Why not $result['This']? I changed this:
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
to this:
$result = array();
while ($query->fetch()) {
foreach ($row as $key => $val) {
$result[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
But why do all the wrappers I see, return a multidimensional array?
Hope you understand me. Thank you!
The reason they return multidimensional arrays is because you can have more than one result.
So:
$data[0]['name'] is the first returned records name.
$data[1]['name'] is the second returned records name.
You can create a fetchRow() function which will always just return the first record when you only expect one row
return $data[0]
OR
a fetchOne()
return $data[0]['name']
When you only expect one field
Usually, when you're gathering results from a DB query, you have multiple rows.
--------------
- 1 --- This -
- 2 --- That -
--------------
So you get a multi-dimensional array in order to handle all the rows in one object.
...Is that not the case here?
EDIT:
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
in the above code, you are assigning each individual row to an index in the $results array. In order to access them, you need to provide $results[ROW_NUMBER][KEY_NAME];
Does that make sense?
I'm going to take a shot and say maybe try $query->fetch_row() instead of $query->fetch() (just a guess)
The MySQL selects are not displaying properly in the PHP / HTML
This is my code:
<?php
session_start();
require_once("database.php");
require_once("MySQL_connection.php");
/* Database connection */
$db = new MySQLConnection($config['sql_host'], $config['sql_username'], $config['sql_password'], $config['sql_database']);
$db->Connect();
unset($config['sql_password']);
/* Cron */
require_once("cron.php");
/* Display Advert */
$ad_link = $db->Query("SELECT `site_url` FROM `adverts` WHERE `zone`=1 AND `days`>0 ORDER BY RAND() LIMIT 0,1;");
$img_link = $db->Query("SELECT `image_url` FROM `adverts` WHERE `zone`=1 AND `days`>0 ORDER BY RAND() LIMIT 0,1;");
?>
<!DOCTYPE html>
<html>
<body>
<img src="<? echo $img_link ?>">
</body>
</html>
For some reason that is displaying as:
<html><head></head><body>
<img src="Resource id #7">
</body></html>
Is anybody know what is wrong?
Forgot to add the code for MYSQL_connection.php, the following code is everything within that file that is used to connect to the DB.
<?php
class MySQLConnection {
private $sqlHost;
private $sqlUser;
private $sqlPassword;
private $sqlDatabase;
private $mySqlLinkIdentifier = FALSE;
public $QueryFetchArrayTemp = array();
private $numQueries = 0;
public $UsedTime = 0;
public function __construct($sqlHost, $sqlUser, $sqlPassword, $sqlDatabase = FALSE) {
$this->sqlHost = $sqlHost;
$this->sqlUser = $sqlUser;
$this->sqlPassword = $sqlPassword;
$this->sqlDatabase = $sqlDatabase;
}
public function __destruct() {
$this->Close();
}
public function Connect() {
if($this->mySqlLinkIdentifier !== FALSE) {
return $this->mySqlLinkIdentifier;
}
$this->mySqlLinkIdentifier = mysql_connect($this->sqlHost, $this->sqlUser, $this->sqlPassword, TRUE); // Open new link on every call
if($this->mySqlLinkIdentifier === FALSE) {
return FALSE;
}
if($this->sqlDatabase !== FALSE) {
mysql_select_db($this->sqlDatabase, $this->mySqlLinkIdentifier);
}
return $this->mySqlLinkIdentifier;
}
public function Close() {
if($this->mySqlLinkIdentifier !== FALSE) {
mysql_close($this->mySqlLinkIdentifier);
$this->mySqlLinkIdentifier = FALSE;
}
}
public function GetLinkIdentifier() {
return $this->mySqlLinkIdentifier;
}
public function Query($query) {
$start = microtime(true);
$result = mysql_query($query, $this->GetLinkIdentifier());
$this->UsedTime += microtime(true) - $start;
$this->numQueries++;
if( $result === false ){
die($this->GetErrorMessage());
}
return $result;
}
public function FreeResult($result) {
mysql_free_result($result);
}
public function FetchArray($result) {
return mysql_fetch_array($result, MYSQL_ASSOC);
}
public function FetchArrayAll($result){
$retval = array();
if($this->GetNumRows($result)) {
while($row = $this->FetchArray($result)) {
$retval[] = $row;
}
}
return $retval;
}
public function GetNumRows($result) {
return mysql_num_rows($result);
}
public function GetNumAffectedRows() {
return mysql_affected_rows($this->mySqlLinkIdentifier);
}
// Helper methods
public function QueryFetchArrayAll($query) {
$result = $this->Query($query);
if($result === FALSE) {
return FALSE;
}
$retval = $this->FetchArrayAll($result);
$this->FreeResult($result);
return $retval;
}
public function QueryFirstRow($query) {
$result = $this->Query($query);
if($result === FALSE) {
return FALSE;
}
$retval = FALSE;
$row = $this->FetchArray($result);
if($row !== FALSE) {
$retval = $row;
}
$this->FreeResult($result);
return $retval;
}
public function QueryFirstValue($query) {
$row = $this->QueryFirstRow($query);
if($row === FALSE) {
return FALSE;
}
return $row[0];
}
public function GetErrorMessage() {
return "SQL Error: ".mysql_error().": ";
}
public function EscapeString($string) {
if (is_array($string))
{
$str = array();
foreach ($string as $key => $value)
{
$str[$key] = $this->EscapeString($value);
}
return $str;
}
return get_magic_quotes_gpc() ? $string : mysql_real_escape_string($string, $this->mySqlLinkIdentifier);
}
function GetNumberOfQueries() {
return $this->numQueries;
}
public function BeginTransaction() {
$this->Query("SET AUTOCOMMIT=0");
$this->Query("BEGIN");
}
public function CommitTransaction() {
$this->Query("COMMIT");
$this->Query("SET AUTOCOMMIT=1");
}
public function RollbackTransaction() {
$this->Query("ROLLBACK");
$this->Query("SET AUTOCOMMIT=1");
}
public function GetFoundRows() {
return $this->QueryFirstValue("SELECT FOUND_ROWS()");
}
public function GetLastInsertId() {
return $this->QueryFirstValue("SELECT LAST_INSERT_ID()");
}
public function QueryFetchArray($query, $all = false, $useCache = true)
{
$tempKey = sha1($query . ($all === true ? 'all' : 'notAll'));
$temp = $this->QueryFetchArrayTemp[$tempKey];
if ($temp && $useCache === true)
{
return unserialize($temp);
}
else
{
$queryResult = $this->Query($query);
$result = $all === true ? $this->FetchArrayAll($queryResult) : $this->FetchArray($queryResult);
$this->QueryFetchArrayTemp[$tempKey] = serialize($result);
return $result;
}
}
}
?>
Using your custom MySQL class, this will probably work:
$result = $db->Query("SELECT `site_url`,`image_url` FROM `adverts` WHERE `zone`=1 AND `days`>0 ORDER BY RAND() LIMIT 0,1;");
while($row = $db->FetchArray($result)) {
echo '<img src="' . $row['image_url'] . '">';
}
$db->FreeResult($result);
However, as others have pointed out, the code used in your custom MySQL class is deprecated and should be updated to use newer php methods/libraries.
You are using some custom MySQL wrapper, but you probably should fetch the result from the query using mysql_result(), mysql_fetch_array() or similar.
You would do well to read up on mysqli, which is a safer way to carry out MySQL queries. You can find the excellent documentation here: http://php.net/manual/en/book.mysqli.php and there is also a very useful tutorial here which covers simple queries like yours: http://www.phphaven.com/article.php?id=65
For your specific question, I would use the following:
$query = "SELECT `site_url`,`image_url` FROM `adverts` WHERE `zone`=1 AND `days`>0 ORDER BY RAND() LIMIT 0,1;";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
if($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
// I've split these lines up to make them a little more readable.
echo '<a href="';
echo $row['site_url'];
echo '">';
echo '<img src="';
echo $row['image_url'];
echo '"</img></a>';
}
}
else {
echo 'NO RESULTS';
}
I hope this helps.
So like when working with mysql_fetch_object(), how do you do things like this:
$array = array();
while($row = mysql_fetch_object($result))
{
$array[] = $row;
}
How do you accomplish that with objects instead of an array? Like,
$object = new stdClass;
while($row = mysql_fetch_object($result))
{
$object[] = $row;
}
Is there a way to do this without a lot of ugly typecasting?
The first method is correct,
it should assign all the objects into $array,
like an array,
you can access via
$arr[0]->$COLUMN ...
I bet you are not referring to this :-
$object = new stdClass;
while($row = mysql_fetch_object($result))
{
$props = "object_{$cnt}";
$object->$props = $row;
++$cnt;
}
The second method is assign each object into property of $object,
and you can assign the property as :-
$object->object_0->$COLUMN ...
Other languages (like C++, C# and Java) support "generics" so you don't have to do "a lot of ugly typecasting". PHP does't - hence the general need for a cast.
But in your case ... if "$row" starts out as an object when you put it into the array ... don't you get the same object back when you de-reference the array?
$object = array();
while($row = mysql_fetch_object($result))
{
$object[] = $row;
}
$object = new stdClass($object);
or
class myClass{
private $counter = 0;
public function add($row){
$count = $counter++;
$this->$count = $row;
}
}
$object = new myClass();
while($row = mysql_fetch_object($result))
{
$object->add($row);
}
or
class myClass implements ArrayAccess{
private $counter = 0;
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$count = $counter++;
$this->$count = $value;
} else {
$this->$offset = $value;
}
}
public function offsetExists($offset) {
return isset($this->$offset);
}
public function offsetUnset($offset) {
unset($this->$offset);
}
public function offsetGet($offset) {
return isset($this->$offset) ? $this->$offset : null;
}
}
$object = new myClass();
while($row = mysql_fetch_object($result))
{
$object[] = $row;
}