How to check if there's no page information found in the database? If I were using foreach to check whether the page is exist or not, I will return false like the example below:
My router file:
$db = new PDO('mysql:host=127.0.0.1;dbname=project1', 'root', '');
$GetDirectory = $db->prepare('
SELECT *
FROM pages
');
$GetDirectory->execute();
$GetDirectory = $GetDirectory->fetchAll(PDO::FETCH_ASSOC);
if (Route::Request_URL()=='/') {
Route::Navigate_URL('home');
} else {
foreach ($GetDirectory as $Directory) {
switch (Route::Request_URL()) {
case strpos(Route::Request_URL(), $Directory['request']) :
if (Route::Verify_URL($Directory['pos1'], $Directory['pos2'], $Directory['request'])!==false) {
Route::Navigate_URL($Directory['name']);
$db = null;
} else {
//this will give an error for each time it didn't found
}
break;
}
}
}
My class file:
class Route {
public static function Request_URL() {
return $_SERVER['REQUEST_URI'];
}
public static function Verify_URL($pos1, $pos2, $url) {
if (strpos(substr(Route::Request_URL(), $pos1, $pos2), $url)!==false) {
return true;
} else {
return false;
}
}
public static function Navigate_URL($RequestURL) {
$db = new PDO('mysql:host=127.0.0.1;dbname=project1', 'root', '');
$ListDirectory = $db->prepare('
SELECT *
FROM pages
');
$ListDirectory->execute();
$ListDirectory = $ListDirectory->fetchAll(PDO::FETCH_ASSOC);
foreach ($ListDirectory as $Directory) {
switch ($RequestURL) {
case $Directory['name'] :
return require_once SERVE_PATH.$Directory['path'];
break;
}
}
}
}
Sorry for the long code. Wanna ask a simpler question, but don't know how to explain.
Related
Hy,
i started learning PHP and i created a simple MVC Style Codebase.
The Script just generates a random number and displays this numer. I also write a function to display the number shown before but it does not work. The value is empty. Can you help me out, i have no clue whats wrong and there is no php error thrown.
view.php
<?php
class View
{
private $model;
private $view;
public function __construct()
{
$this->model = new Model();
}
public function output()
{
echo 'Current Entry: ';
echo $this->model->getData();
echo '<br />';
echo 'Update';
echo '<br />';
echo 'Last';
}
public function getModel()
{
return $this->model;
}
}
controller.php
<?php
class Controller
{
private $model;
private $view;
public function __construct($view)
{
$this->view = $view;
$this->model = $this->view->getModel();
}
public function get($request)
{
if (isset($request['action']))
{
if ($request['action'] === 'update')
{
for ($i = 0; $i<6; $i++)
{
$a .= mt_rand(0,9);
}
$this->model->setData($a);
}
elseif ($request['action'] === 'preview')
{
$this->model->setLast();
}
else
{
$this->model->setData('Wrong Action');
}
}
else
{
$this->model->setData('Bad Request');
}
}
}
model.php
<?php
class Model
{
private $data;
private $last;
public function __construct()
{
$this->data = 'Default';
}
public function setData($set)
{
if ( ! (($set == 'Wrong Action') && ($set == 'Bad Request')))
{
$this->last = $this->data;
}
$this->data = $set;
}
public function getData()
{
return $this->data;
}
public function setLast()
{
$this->data = $this->last;
}
public function getLast()
{
return $this->last;
}
}
index.php
<?php
require_once 'controller.php';
require_once 'view.php';
require_once 'model.php';
$view = new View();
$controller = new Controller($view);
if (isset($_GET) && !empty($_GET)) {
$controller->get($_GET);
}
$view->output();
Are there any other, bad mistakes in the Script?
Any input very welcome! :)
The problem with your code is that PHP does not preserve variable values between requests, therefore, when you set your $model->last value here:
$this->last = $this->data;
It gets reset on your next request.
You may want to store $last value in a session or a cookie instead. Something like:
$_SESSION['last'] = $this->data;
And then when you are instantiating your model you could initialize it with a value stored in a session if available:
index.php - add session_start() at the beginning
model.php:
public function __construct()
{
$this->data = isset($_SESSION['last']) ? $_SESSION['last'] : 'Default';
}
public function setData($set)
{
$this->data = $set;
if ( ! (($set == 'Wrong Action') && ($set == 'Bad Request')))
{
$_SESSION['last'] = $this->data;
}
}
controller.php
elseif ($request['action'] === 'preview')
{
//Remove this
//$this->model->setLast();
}
In the following code, the function parseImages is not implemented.
Can someone help me to call the function parseImages in the foreach:
foreach ($listFeatured as &z$product) {
$product['description'] = substr(trim(strip_tags($product['description_short'])), 0, $maxDesc);
$product['price'] = Tools::displayPrice($product['price']);
$product = $this->parseImages($product, $params);
$product = $this->generateImages($product, $params);
}
function parseImages($product, $params) {
global $link;
$isRenderedMainImage = $params->get("cre_main_size", 0);
if (_PS_VERSION_ <= "1.5.0.17") {
$mainImageSize = $params->get("main_img_size", 'thickbox');
} else {
$mainImageSize = $params->get("main_img_size", 'thickbox_default');
}
if ($isRenderedMainImage) {
if ((int) Configuration::get('PS_REWRITING_SETTINGS') == 1) {
$product["mainImge"] = $this->getImageLink($product["link_rewrite"], $product["id_image"]);
} else {
$product["mainImge"] = $link->getImageLink($product["link_rewrite"], $product["id_image"]);
}
} else {
$product["mainImge"] = $link->getImageLink($product["link_rewrite"], $product["id_image"], $mainImageSize);
}
$product["thumbImge"] = $product["mainImge"];
return $product;
}
This is a piece of a module of Prestashop and I want to use it twice.
If solved I will share the solution to all Prestashop users.
You're using as an object method $this->parseImages() but you defined it as a function:
function parseImages($product, $params) {
[...]
}
You can keep this function like this and use parseImages() without the $this-> or if you're inside a class change your function declaration to this:
public function parseImages($product, $params) {
[...]
}
You should read some documentation about OOP
For a small home project I am working on I have been looking for OO design patterns for Memcache implementation, but so far haven't found something I feel fits, so maybe my approach is wrong.
I have a DB connection class and an baseModel class so I want to implement caching on the baseModel where appropriate.
I have implemented the Database connection and the Cacher as Singlton patterns.
I cannot seem to get the Cacher class to read the data or trigger the echo "<p>Getting from cache"; line after I refresh the page on the base Model "loadFromDb" function
Here are the classes:
class Cacher {
protected static $cacher = null;
private static $settings;
public static function getCache() {
if (self::$cacher != null) {
return self::$cacher;
}
try {
self::$settings = parse_ini_file("./configs/main.ini");
self::$cacher = new Memcache();
self::$cacher->connect(
self::$settings['cache_server_host']
, self::$settings['cache_server_port']
);
} catch (Exception $e) {
// TODO log error and mitigate..
echo "Error connecting memcache";
die();
}
var_dump(self::$cacher->getstats());
return self::$cacher;
}
public static function getData($key) {
if (self::$cacher == null) {
self::getCache();
}
return self::$cacher->get($key);
}
public static function setData($key, $data, $expire = 0) {
if (self::$cacher == null) {
self::getCache();
}
if (self::$cacher)
return self::$cacher->set($key, $data, MEMCACHE_COMPRESSED, $expire);
}
}
class ModelBase {
protected $fields = array();
protected $class = null;
function __construct($class_name) {
$this->class = $class_name;
$this->fields = Database::getFields($class_name);
}
public function loadFromDB($id, $fromCache = true) {
$key = "loadFromDB_{$this->class}_{$id}";
if ($fromCache) {
$data = Cacher::getData($key);
if ($data) {
echo "<p>Getting from cache";
return unserialize($data);
} else {
echo "<p>No cache data. going to DB";
}
}
$values = Database::loadByID($this->class, $this->fields[0], $id);
foreach ($values as $key => $val) {
$this->$key = $val;
}
$dataSet = Cacher::setData($key, serialize($this));
echo "<p>Data set = $dataSet";
}
}
Memcache service is running and I can read data directly back if I read the cache directly after I write it, but what I want is to read the data from the DB only the first time the page loads, after that use the cache....
Any comments welcome...
Try doing it like (let the result of the cache decide if you should query the db):
<?php
public function loadFromDB($id) {
$key = "loadFromDB_{$this->class}_{$id}";
//query cache
$data = Cacher::getData($key);
//is it found
if (!empty($data)) {
//echo "<p>Getting from cache";
return unserialize($data);
}
//no so lest query db
else {
//echo "<p>No cache data. going to DB";
$values = Database::loadByID($this->class, $this->fields[0], $id);
foreach ($values as $key => $val) {
$this->$key = $val;
}
//store it in cache
//$dataSet = Cacher::setData($key, serialize($this));
$dataSet = Cacher::setData($key, serialize($values));//<<store the db result not the class
}
//echo "<p>Data set = $dataSet";
return unserialize($dataSet);
}
?>
I'm using MySQL(i)-community-5.3 if not mistaken. After finally getting the hang of PDO, I can now conclude that the infected sectore is that which processes binding, all other functions are fine (that I know of). Below I will present a function which works and also doesn't work (the sequence without anything to do with binding works flawlessly.
Function you() is as followes:
public function you($row) {
if(isset($_COOKIE["SK"])) {
$usr = $this->baseXencode($_SESSION["username"]);
$q = "SELECT $row FROM SN_users WHERE username=:USR";
$this->netCore->q($q);
$this->netCore->bind(":USR", $usr);
$result = $this->netCore->single();
$result = $result[$row];
} else {
$q = "SELECT $row FROM SN_users WHERE username='".$this->baseXencode("Anonymous")."' AND password='".$this->baseXencode("Anonymous")."'";
$result = $this->netCore->q($q);
$result = $this->netCore->single();
$result = $result[$row];
}
return $result;
}
}
(As you can see, when pre-allocating the username/password combo for Anonymous users, the function executes perfectly whereas binding within the if() section does not, returning the value 1.
Below is my binding function bind() (if you may require any other code, I will edit this post further~^^):
EDIT:
Below is the netCore class:
class netCore {
private $boot;
private $dbHost = "";
private $dbNAME = "";
private $dbPASS = "";
private $dbUSR = "";
private $err;
private $state;
public function __construct() {
$bootloadr = "mysql:host=".$this->dbHost.";dbname=".$this->dbNAME.";charset=UTF8";
$opt = array(PDO::ATTR_PERSISTENT => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
try {
$this->boot = new PDO($bootloadr, $this->dbUSR, $this->dbPASS, $opt);
} catch(PDOException $e) {
$this->err = "<b>Lebensborn® netCore™ Error:</b> An exception has been raised during Network-to-Database procedures.<br /><b>Message:</b> ".$e->getMessage().".";
}
}
public function bind($param, $value, $type = NULL) {
if(is_null($type)) {
switch(true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->state->bindParam($param, $value, $type);
}
public function debug() {
return $this->state->debugDumpParams();
}
public function exe() {
return $this->state->execute();
}
public function count() {
$this->exe();
return $this->state->fetchColumn();
}
public function q($q) {
$this->state = $this->boot->prepare($q);
}
public function set() {
$this->exe();
return $this->state->fetchAll(PDO::FETCH_ASSOC);
}
public function single() {
$this->exe();
return $this->state->fetch(PDO::FETCH_ASSOC);
}
public function transBegin() {
return $this->boot->beginTransaction();
}
public function transCancel() {
return $this->boot->rollBack();
}
public function transEnd() {
return $this->boot->commit();
}
}
i am writing a MySQL wrapper class to:
a.) replace a current one
b.) make life easier in terms of custom functionality
c.) to learn and improve
I am looking on advice on how to improve my techniques and coding style, so i would appreciate any input you could provide.
DISCLAIMER:
I am aware there are other database abstraction methods such as PDO but i wanted to write my own for the above reasons
Thanks,
Lee
Test Call
#!/usr/bin/php
<?php
include('mysql.class.php');
$_mysql = new mysqli_ls( array( 'debug_log' => TRUE, 'query_log' => TRUE ) );
if ($_mysql->connect('host','user','password','db') === FALSE) print_r( $_mysql->get_error() );
else print "#1 connected\n";
if ($_mysql->set_database('auth_tracker_test') === FALSE) print_r( $_mysql->get_error() );
else print "#1 database changed\n";
/// Execute standard query
$sql = "SELECT * from user";
if ($_mysql->SQLQuery($sql) === TRUE) print "#1 SELECT Query worked\n";
else print print_r( $_mysql->get_error() );
#print_r($_mysql->getArray());
print_r($_mysql->getRow());
$_mysql->disconnect();
?>
<?php
class mysqli_ls
{
/**************************************************************************/
/* SETUP VARIABLES */
/**************************************************************************/
private $E_OK = TRUE;
private $E_ERROR = FALSE;
private $db_host;
private $db_user;
private $db_port;
private $db_name;
private $db_pass;
private $result;
private $link = FALSE;
private $errorArr = array();
private $config = array( // Location of exisiting
'config_load' => FALSE,
'config_path' => 'database.cfg.php',
// Record errors to a file
'debug_log' => FALSE,
'debug_log_path' => '/tmp/mysql.debug.log',
// Record queries to a file
'query_log' => FALSE,
'query_log_path' => '/tmp/mysql.debug.log' );
private $fh_debug = FALSE;
private $fh_query = FALSE;
private $fh_config = FALSE;
/**************************************************************************/
/* MAGIC FUNCTIONS */
/**************************************************************************/
public function __construct( $config = '' )
{
// Config vars
if ( !empty($config) && is_array($config) ) $this->set_config($config);
// Open file handles if logs are required
// Debug Log
if ($this->config['debug_log'] === TRUE)
{
if (! $this->fh_debug = fopen($this->config['debug_log_path'], 'a') )
{
$this->handle_error('#01A', 'could not open debug log');
return $this->E_ERROR;
}
}
// Query Log
if ($this->config['query_log'] === TRUE)
{
if (! $this->fh_query = fopen($this->config['query_log_path'], 'a') )
{
$this->handle_error('#01B', 'could not open query log');
return $this->E_ERROR;
}
}
// Check mysqli functions are available
if (!function_exists('mysqli_connect'))
{
$this->handle_error('#01C', 'mysqli not installed');
return $this->E_ERROR;
}
return $this->E_OK;
}
public function __deconstruct()
{
if ($this->link) $this->disconnect();
return $this->E_OK;
}
/**************************************************************************/
/* CONNECTION MANAGEMENT */
/**************************************************************************/
public function connect($db_host='', $db_user='', $db_pass='', $db_name, $db_port='3306')
{
if (empty($db_host) || empty($db_user) || empty($db_pass) || empty($db_name) || empty($db_port))
{
$this->handle_error('#02A', 'Missing connection variables');
return $this->E_ERROR;
}
$this->db_host = $db_host;
$this->db_user = $db_user;
$this->db_pass = $db_pass;
$this->db_name = $db_name;
$this->db_port = $db_port;
$this->link = #new mysqli($this->db_host, $this->db_user, $this->db_pass, $this->db_name, $this->db_port);
if (mysqli_connect_error($this->link))
{
$this->handle_error(mysqli_connect_errno($this->link), mysqli_connect_error($this->link));
return $this->E_ERROR;
}
return $this->E_OK;
}
public function disconnect()
{
if ($this->link)
{
if ($this->link->close() === TRUE) return $this->E_OK;
else
{
$this->handle_error($this->link->errno, $this->link->error);
return $this->E_ERROR;
}
}
$this->handle_error('#03A','no activate database connection');
return $this->E_ERROR;
}
public function connect_existing()
{
}
public function set_database($database)
{
if ( $this->link->select_db($database) === FALSE )
{
$this->handle_error($this->link->errno, $this->link->error);
return $this->E_ERROR;
}
$this->E_OK;
}
/**************************************************************************/
/* SQL INTERFACE */
/**************************************************************************/
public function insert()
{
}
public function update()
{
}
public function delete()
{
}
public function select()
{
}
public function query($sql)
{
// If the result set has cleaned up, do so before a new query
if ($this->result) $this->result->close();
// Record query
if ($this->config['query_log'] === TRUE) $this->write_log('query', $sql);
if ($result = $this->link->query($sql));
{
$this->result = $result;
return $this->E_OK;
}
// Clean up the result set
$result->close();
// Query failed, handle error
$this->handle_error($this->link->errno, $this->link->error);
return $this->E_ERROR;
}
/**************************************************************************/
/* RESULT FUNCTIONS */
/**************************************************************************/
public function getArray($type = 'assoc')
{
switch($type)
{
case 'num':
$type = MYSQLI_NUM;
break;
case 'assoc':
$type = MYSQLI_ASSOC;
break;
case 'both':
$type = MYSQLI_BOTH;
break;
default:
$this->handle_error('#12A','invalid field type. Options are include num, assoc, both');
return $this->E_ERROR;
break;
}
$resultArr = array();
while( $row = $this->result->fetch_array( $type ) )
{
$resultArr[] = $row;
}
return $resultArr;
}
public function getRow($type = 'assoc')
{
switch($type)
{
case 'num':
$type = MYSQLI_NUM;
break;
case 'assoc':
$type = MYSQLI_ASSOC;
break;
case 'both':
$type = MYSQLI_BOTH;
break;
default:
$this->handle_error('#13A','invalid field type. Options are include num, assoc, both');
return $this->E_ERROR;
break;
}
return $this->result->fetch_array( $type );
}
public function num_row()
{
return $this->result->num_rows;
}
public function insert_id()
{
return $this->link->insert_id;
}
public function affected_rows()
{
return $this->link->affected_rows;
}
/**************************************************************************/
/* LEGACY SUPPORT */
/**************************************************************************/
public function SQLQuery($sql='')
{
if (empty($sql))
{
$this->handle_error('#19A','missing query string');
return $this->E_ERROR;
}
// Check for a select statement
if ( preg_match("/^select/i",$sql) === 0)
{
$this->handle_error('#19A','incorrect query type, SELECT expected');
return $this->E_ERROR;
}
// Execute query
if ($this->query($sql) === $this->E_ERROR) return $this->E_ERROR;
// Return number of rows
return $this->num_row();
}
public function SQLModify($sql='')
{
if (empty($sql))
{
$this->handle_error('#19A','missing query string');
return $this->E_ERROR;
}
// Execute query
if ($this->query($sql) === $this->E_ERROR) return $this->E_ERROR;
// Return affected rows
$this->affected_rows();
}
public function numRow()
{
return $this->num_row();
}
/**************************************************************************/
/* LOGGING AND DEBUGGING */
/**************************************************************************/
private function write_log($type, $msg)
{
$msg = date('Y-m-d H:i:s') ."\t". $type ."\t". $msg ."\n";
switch($type)
{
case 'error':
fwrite($this->fh_debug, $msg);
break;
case 'query':
fwrite($this->fh_query, $msg);
break;
default:
return $this->E_ERROR;
break;
}
}
private function handle_error($errormsg, $errorno)
{
$this->errorArr[] = array( 'code' => $errorno,
'error' => $errormsg );
if ($this->config['debug_log'] === TRUE)
{
$msg = "($errorno) $errormsg";
$this->write_log('error', $msg);
}
return $this->E_OK;
}
public function get_error($type = 'string')
{
switch($string)
{
case 'string':
$error = end($this->errorArr);
return $error['error'] .' ('. $error['code'] .')';
break;
case 'array':
return end($this->errorArr);
break;
}
return false;
}
/**************************************************************************/
/* SET CONFIG VARS */
/**************************************************************************/
public function set_config($config)
{
foreach ($config as $key => &$value)
{
if ( ! isset($this->config[$key]) )
{
$this->handle_error('#19A','invalid field type');
return $this->E_ERROR;
}
$this->config[$key] = $value;
}
return $this->E_OK;
}
/**************************************************************************/
} // Class END
?>
I made one myself once and added another class named MySqlTable, which represented a table. I returned it in the __GET function, so you could call a table with
$sql->tablename->select();
Here's the code for the __get function:
function __GET($name)
{
return new MySqlTable($this, $name);
}
The class was like this:
class MySqlTable
{
private $table;
private $mySql;
function MySqlTable(&$oMySql, $sTable)
{
$this->mySql = $oMySql;
$this->table = $sTable;
}
function &select($sWhere = '')
{
if (empty($sWhere))
{
$data = $this->mySql->query("SELECT * FROM " . $this->table);
}
else
{
$data = $this->mySql->query("SELECT * FROM " . $this->table . " WHERE " . $sWhere);
}
return $this->mySql->resultToArray($data);
}
}
Currently, your mysqli_ls class contains the result of a query. This makes it impossible to do two queries and use the results of the first query after the second query ran.
A better way would be to let the SQLQuery() method return a result object, which contains the result handle and methods to retrieve rows from the result.