How to persist data in a PHP application - php

Why might a static variable I've initialized in a class become unset? Here is class( is 'static' ):
class Events {
// static events collection
private static $events = null;
// private(unused) constructor
private function __construct() {}
// initializes the class
public static function initialize($events){
self::$events = $events;
}
// returns the event collection
public static function get(){
return self::$events;
}
}
I set $events like this:
functions.php:
include_once "events.php";
// a function to initialize the application
function init(){
// retrieve events from database
$events = get_events_from_server();
// initialize the events class
Events::initialize($events);
}
init() is called from index.php.
The variable seems to be unset after index.php has completely loaded. I post from javascript to a server page: get_events.php to request the list of json encoded events. At get_events.php the static events variable is null. Here is get_events.php:
<?php
include_once "../ccc-psl-config.php";
include_once WEBROOT ."/includes/functions.php";
include_once WEBROOT ."/includes/db_connect.php";
include_once WEBROOT ."/types/events.php";
ob_start();
try{
// open database connection
$pdo = DatabaseConnection::open();
$events = Events::get();
//$events = get_events($pdo);
if($events){
echo $events;
}
else {
echo false;
}
}
catch(Exception $e){
print_r("Failed to get events from database: ".$e.getMessage());
echo false;
}
// close database connection
DatabaseConnection::close();
ob_end_flush();

Related

PHP Class example

Can anyone help me with php classes example. I have to make class "information" that has information about users: id, email, password, first name, last name, phone.
Also, class must have a method to print all the user data on the output.
It's really simple skeleton, because you didn't try anything, so just for you to have idea how it works...
class User
{
private $id;
private $email;
// ...
public function __construct($id, $email...)
{
$this->id = $id;
$this->email = $email;
// ...
}
public function printAll()
{
return $this->id . ' ' . $this->email;
}
}
I suggest you reading this: http://codular.com/introducing-php-classes and then come back with any questions.
Here is an example of a PHP class:
class DBIGenerator{
private $table;
private $name;
private $path;
public function __construct($table,$name='default_file.php',
$path='DEFAULTPATH/'){
$this->table=$table;
$this->name=$name;
$this->path=$path;
}
public function generate(){
// build class header
$str='<?php class '.$this->name.'{';
if(!$result=mysql_query('SHOW COLUMNS FROM '.$this->table)){
throw new Exception('Failed to run query');
}
// build data member declaration
if(mysql_num_rows($result)<1){
throw new Exception('Not available columns in table');
}
$methods='';
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
$str.='private $'.$row['Field'].'=\'\';';
$methods.='public function set'.$row['Field'].'($'.$row
['Field'].'){$this->'.$row['Field'].'=$'.$row
['Field'].';}';
$methods.='public function get'.$row['Field'].'(){return
$this->'.$row['Field'].';}';
// store field names in array
$fields[]=$row['Field'];
}
// build empty constructor
$str.='public function __construct(){}';
// build modifiers and accessors
$str.=$methods;
// build load() method
$str.='public function load(){$r=mysql_query("SELECT * FROM
'.$this->table.' WHERE id=\'$this->id\'");';
$str.='return mysql_fetch_array($r,MYSQL_ASSOC);}';
// build submit() method
$str.='public function submit(){mysql_query("INSERT INTO '.$this-
>table.' SET ';
foreach($fields as $field){
$str.=($field!='id')?$field.'=\'$this->'.$field.'\',':'';
}
$str.='");$this->id=mysql_insert_id();';
$str=preg_replace("/,\"/","\"",$str).'}';
// build update() method
$str.='public function update(){mysql_query("UPDATE '.$this-
>table.' SET ';
foreach($fields as $field){
$str.=($field!='id')?$field.'=\'$this->'.$field.'\',':'';
}
$str=preg_replace("/,$/","",$str);
$str.=' WHERE id=\'$this->id\'");}';
// build delete() method
$str.='public function delete(){mysql_query("DELETE FROM '.
$this->table.' WHERE id=\'$this->id\'");}';
$str.='}?>';
// open or create class file
if(!$fp=fopen($this->path.$this->name.'.php','w')){
throw new Exception('Failed to create class file');
}
// lock class file
if(!flock($fp,LOCK_EX)){
throw new Exception('Unable to lock class file');
}
// write class code to file
if(!fwrite($fp,$str)){
throw new Exception('Error writing to class file');
}
flock($fp,LOCK_UN);
fclose($fp);
// delete temporary variables
unset($fp,$str,$row,$fields,$field,$methods);
}
public function getObject(){
// check if class file exists
if(!file_exists($this->path.$this->name.'.php')){
throw new Exception('Failed to include class file');
}
require_once($this->path.$this->name.'.php');
// create data access object
return new $this->name;
}
}
Read more at http://www.devshed.com/c/a/PHP/Building-ObjectOriented-Database-Interfaces-in-PHP-Updating-the-Application-to-PHP-5/1/#Czocu1kMhhuTvg2e.99
Take a look at the snippet below as a basic way to implementing as expressed:
<?php
class information
{
public $id = 1;
public $email = "mail#mail.com";
public $pw = "A2D7DFEA88AC88"; //Don't forget, PW are usually hashed ;)
public function id() {
echo $this->id;
}
public function email() {
echo $this->email;
}
public function pw() {
echo $this->pw;
}
}
$test = new information();
$test->id;
?>

Execute a callback before and after each instance method call?

I've a shared $sdk object reference (it's Facebook PHP SDK) between many objetcs. I need to save the access token at very beginning of a function call and restore after $this->sdk->api call. See for example getAlbums() function.
How can automatically execute a callback before/after every function call on every FBItem instance?
abstract class Item
{
protected $id, $sdk, $auth;
public function __construct(Facebook $sdk, $auth = null)
{ $this->sdk = $sdk; $this->auth = $auth; }
public function getAlbums() // Require access token change
{
// Am i FBUser or FBPage? Call setAccessToken to set auth
$backup = $this->sdk->getAccessToken();
$this->sdk->setAccessToken($auth ?: $backup);
$as = array();
$rs = $this->sdk->api(sprintf('/%s/albums', $this->id));
foreach($rs['data'] as $i) $as[] = new Album($this->sdk, $this->auth);
// Restore previous token backup
$this->sdk->setAccessToken($backup);
}
}
class User extends Item
{
$ps = array(); $rs = $this->sdk->api(sprintf('/%s/accounts', $this->id));
foreach($rs['data'] as $i) $ps[] = new Page($this->sdk, $i['access_token']);
return $ps;
}
class Page extends Item { }
Probably the only way (without using php rootkit or rewriting whole classes) is preparing wrapper such as this:
class FBItemWrapper {
public $item = new FBItem();
public function __call( $functionName, $args){
// Pre callback
$result = call_user_func_array( array( $this->item, $functionName), $args);
// Post callback
return $result;
}
}
You may set object dynamically so one Wrapper will be enough for everything.

Accessing a Local Variable through Xajax and Classes in PHP

I have a Class
<?php
class cms{
private $dataset;
private $columns;
private $configs;
public function __construct(){
global $frw, $dbg;
$this->configs =array();
}
public function __get($key){
if(array_key_exists($key, $this->configs)==true){
return $this->configs[$key];
}else{
throw new Exception('Unable to get value from configuration. '.$key);
}
}
public function __set($key, $value){
if(array_key_exists($key,$this->configs)){
throw new Exception('Unable to set configuration. '.$key);
}else{
$this->configs[$key] = $value;
}
}
public function exists($key){
if(isset($this->configs[$key])){
return true;
}else{
return false;
}
}
public function load(){
}
}
?>
$cms = new $cms;
I need to have a variable set on the page that instatiates the object and is available globally throughout each page (for duration of session). I do not want a session variable and I'd like not to use a global. Is there a way of passing the $dataset between pages and calling $cms->dataset in an xajax load. I keep thinking that I should be able to set a variable $dataset = $cms->__get('dataset');
Declare $dataset as public right now private $dataset is not accessible out side the class
public $dataset;
will be accessible outside the class
$cms->dataset

including class within another class in php

i have a php page which has some variables regarding database i.e server address, username and password etc.
config.php will include
<?php
$dbserver="";
$username="";
$password="";
$database="";
?>
i have a class which contains all the functions required for my website. How can i import my php page variables into this class to be used for the database connectivity?
my class
<?php
class a{
include("config.php");
function db_connect(){
mysql_connect($dbserver,$username,$password);
}
}
?>
usually for this purpose, Constants exist.
But if you want to use variables, all you have to do is to require_once(yourFile), then when you want to use these variables (which are global) inside a method of a class, simply refer to them as global $myVar; (as if you're declaring it). Only need to do this once for each global variable you want to use in the context.
Example:
settings.php:
$conn = 'my connection';
MyClass.php:
class MyClass
{
function DoSomething()
{
require_once('settings.php');
global $conn;
doSomethingWith($conn);
}
}
Update
For a Database class that requires configuration options, the simplest way would be to use the config values as parameters (example 1 of my original answer below).
A more complex, though also more flexible approach would be a Config-Class.
class Config
{
private $config = array();
public function __construct(array $config)
{
$this->config = $config;
}
public function Register($key, $value)
{
$this->config[$key] = $value;
}
public function Get($key)
{
if (!isset($this->config[$key])) return null;
return $this->config[$key];
}
}
Your DB class would look something like this:
class Database
{
private $config = null;
public function __construct(Config $config)
{
$this->config = $config;
}
public function Connect()
{
do_connect_stuff($this->config->Get('host'), $this->config->Get('user'), .....);
}
}
File config.php
<?php
$config = new Config(
array(
"host" => "localhost",
"user" => "user",
...
)
);
/*
alternative:
$config = new Config();
$config->Register('host', 'localhost');
$config->Register('user', 'user');
...
*/
?>
File that requires the database:
<?php
$database = new Database($config);
$database->Connect();
?>
As a side hint: Use PDO, it's far better than the old mysql_* functions.
Original Answer
The proper style would be to pass the variables to the functions as parameter or pass them when creating the object. You can also use Init methods to pass the parameters.
Examples:
(Which of the following code you should use depends on what you already have and how your code is designed, the 'cleanest' way would be an object for which you transmit the variables when calling the ProcessAction method)
Assuming that in your script you have a Variable $action which you get from $_GET or some other way.
Using an Object
class Controller
{
public function ProcessAction($action, $some_other_parameter, $and_yet_another_parameter)
{
[...]
}
}
You then call it with
$action = do_some_stuff_to_get_action();
$controller = new Controller();
$controller->ProcessAction($action, $other_parameter, $second_parameter);
Using a static class
class Controller
{
public static function ProcessAction($action, $some_other_parameter, $and_yet_another_parameter)
{
[...]
}
}
Called with:
$action = do_some_stuff_to_get_action();
Controller::ProcessAction($action, $other_parameter, $second_parameter);
Passing the parameters before calling the function
Object
class Controller
{
private $action = "";
private $some_other_parameter = "";
public function __construct($action, $some_other_parameter)
{
$this->action = $action;
$this->some_other_parameter = $some_other_parameter;
}
public function ProcessAction()
{
if ($this->action == 'do_stuff')
{
[...]
}
}
}
Called with:
$action = do_some_stuff_to_get_action();
$controller = new Controller($action, $other_parameter);
$controller->ProcessAction();
Static methods
class Controller
{
private static $action = "";
private static $some_other_parameter = "";
public static function Init($action, $some_other_parameter)
{
self::$action = $action;
self::$some_other_parameter = $some_other_parameter;
}
public static function ProcessAction()
{
if (self::$action == 'do_stuff')
{
[...]
}
}
}
Called with:
$action = do_some_stuff_to_get_action();
Controller::Init($action, $other_parameter);
Controller::ProcessAction();
I used the database configuration in the constructor of the class. I think that was the only solution not including any third page in the scenario.

set session in database in php

How can I use session in database table with php and mysql?
You would need to create an object like so:
class SessionHandler
{
private static $lifetime = 0;
private function __construct() //object constructor
{
session_set_save_handler(
array($this,'open'),
array($this,'close'),
array($this,'read'),
array($this,'write'),
array($this,'destroy'),
array($this,'gc')
);
}
public function start($session_name = null)
{
session_start($session_name); //Start it here
}
public static function open()
{
//Connect to mysql, if already connected, check the connection state here.
return true;
}
public static function read($id)
{
//Get data from DB with id = $id;
}
public static function write($id, $data)
{
//insert data to DB, take note of serialize
}
public static function destroy($id)
{
//MySql delete sessions where ID = $id
}
public static function gc()
{
return true;
}
public static function close()
{
return true;
}
public function __destruct()
{
session_write_close();
}
}
Then before session_start initiate this class!
include 'classes/sessionHandlerDB.php';
$session = new SessionHandler();
$session->start('userbase');
$_SESSION['name'] = 'Robert Pitt'; //This is sent to SessionHandler::write('my_id','Robert Pitt')
echo $_SESSION['name']; //This calls SessionHandler::read($id)//$id is Unique Identifier for that
http://php.net/manual/en/function.session-set-save-handler.php
http://php.net/manual/en/function.serialize.php
You control this in php.ini under the session_handler directive. Check out http://www.tonymarston.net/php-mysql/session-handler.html for a easy walk through (used it before).
You'll need to usesession_set_save_handler to write custom open, close, read, write, destroy, and garbage collection functions.
See my github code snippet PHP5.4-DB-Session-Handler-Class for a database driven session management class in PHP 5.4.

Categories