I'm trying to figure out why the code below won't persist my $_SESSION['objSession'] object across pages unless i keep the serialize/unserialize in place below. I get tired of manually serializing/unserializing to make object changes in the session and people keep saying i shouldn't have to do it but i do see other complaints about session objects not persisting without it on the web including here on stack... PHP 5.3 Apache 2.2 Windows 2008.
<?php require_once("/php/php_clsSession.php");?>
<?php session_start(); ?>
<?php
// Session Object Create/Log
$objSession = new clsSession;
if ( !(isset($_SESSION['objSession']) )) {
// This line will populate some properties in the obj
// like Session_ID and Create_dt
$objSession->CreateSession(session_id(),$_SERVER);
}
else {
// this code will only run if the session is already
// set
$objSession = unserialize($_SESSION['objSession']);
$objSession->UpdateSession(session_id(),$_SERVER);
}
// Update Session Object
$_SESSION['objSession'] = serialize($objSession);
unset($objSession);
?>
---- clsSession Below this line... you can ignore the db include as the code has the same problem without using the db functionality and i have the db function temporarily commented anyhow....
<?php
// -----------------------------------------------------------------
// Program Type: Class
// Program Name: clsSession
// Program Date: 01/08/2012 Programmer: Tim Wiley
// Description: Standard class for session creation/update
// -----------------------------------------------------------------
class clsSession {
// Properties
public $Session_Id = null;
public $Creation_Dt = null;
public $Action_Dt = null;
public $Session_IP_Address = null;
public $Browser_Type = null;
public $Display_Resolution = null;
public $Is_Https_Ind = null;
public $Is_Logged_In_Ind = 0;
public $User_Key = null;
public $User_Id = null;
public $Email_Address = null;
public $Request_Method = null;
public $Page_Requested = null;
public $Page_Request_Params = null;
public $Page_Action = null;
public $Login_Attempts = 0;
public $Max_Login_Attempts = 3;
private function UpdateSessionClassData (&$xSessionId = null, &$xSessionObj = null, &$xPageAction = "N/A" ) {
$this->Session_Id = &$xSessionId;
$this->Action_Dt = date( 'Y-m-d H:i:s', time( ));
$this->Session_IP_Address = substr(trim(&$xSessionObj['REMOTE_ADDR']),0,24);
$this->Browser_Type = substr(trim(&$xSessionObj['HTTP_USER_AGENT']),0,140);
$this->Request_Method = substr(trim(&$xSessionObj['REQUEST_METHOD']),0,24);
$this->Page_Requested = substr(trim(&$xSessionObj['SCRIPT_NAME']),0,140);
$this->Page_Request_Params = substr(trim(&$xSessionObj['QUERY_STRING']),0,140);
$this->Is_Https_Ind = &$xSessionObj['SERVER_PORT'] == 443 ? 1 : 0;
if (is_null($this->Display_Resolution)) {
require_once('/javascript/js_SaveScreenResolutionInCookie.js');
$this->Display_Resolution = !( IS_NULL( $_COOKIE['users_resolution'] )) ? substr(trim($_COOKIE['users_resolution']),0,16) : "N/A";
}
$this->Page_Action = substr(trim(&$xPageAction),0,32);
}
// Initialize Session objSession for $_SESSION
public function CreateSession($xSessionId = null, &$xSessionObj = null ) {
$this->Creation_Dt = date( 'Y-m-d H:i:s', time( ));
$this->UpdateSessionClassData(&$xSessionId, &$xSessionObj);
// $this->WriteSessionToDb();
}
// Update Session objSession for $_SESSION
public function UpdateSession($xSessionId = null, &$xSessionObj = null, $xPageAction = "N/A" ) {
$this->UpdateSessionClassData(&$xSessionId, &$xSessionObj, &$xPageAction);
// $this->WriteSessionActivityToDb();
}
// Writes the session data to database
public function WriteSessionToDb($xUserType = "Web") {
$objConnect = new clsDb;
$objDb = $objConnect->GetDbConnection($xUserType);
//$objDb = $this->GetDbConnection($xUserType);
$_InsertSQL = new PDOStatement;
$_InsertSQL = $objDb->prepare("INSERT INTO T_SESSION_STATS(" .
"F_ACTION_DT, F_SESSION_ID, F_SESSION_IP_ADDRESS, F_BROWSER_TYPE," .
"F_DISPLAY_RESOLUTION, F_PAGE_REQUESTED, F_PAGE_REQUEST_PARAMS," .
"F_REQUEST_METHOD, F_IS_HTTPS_IND, F_IS_LOGGED_IN_IND, F_USER_KEY)" .
"Values (?,?,?,?,?,?,?,?,?,?,?)");
$_InsertSQL->bindParam(1, $this->Action_Dt );
$_InsertSQL->bindParam(2, $this->Session_Id );
$_InsertSQL->bindParam(3, $this->Session_IP_Address );
$_InsertSQL->bindParam(4, $this->Browser_Type );
$_InsertSQL->bindParam(5, $this->Display_Resolution );
$_InsertSQL->bindParam(6, $this->Page_Requested );
$_InsertSQL->bindParam(7, $this->Page_Request_Params );
$_InsertSQL->bindParam(8, $this->Request_Method );
$_InsertSQL->bindParam(9, $this->Is_Https_Ind );
$_InsertSQL->bindParam(10, $this->Is_Logged_In_Ind );
$_InsertSQL->bindParam(11, $this->User_Key );
try {
$objDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$objDb->beginTransaction();
$_InsertSQL->execute();
$objDb->commit();
unset($objDb);
} catch (Exception $e) {
$objDb->rollBack();
echo "Failed: " . $e->getMessage();
unset($objDb);
unset($objConnect);
}
}
// Writes the session data to database
public function WriteSessionActivityToDb($xUserType = "Web",$xPageAction = "N/A") {
$objConnect = new clsDb;
$objDb = $objConnect->GetDbConnection($xUserType);
//$objDb = $this->GetDbConnection($xUserType);
$_InsertSQL = new PDOStatement;
$_InsertSQL = $objDb->prepare("INSERT INTO T_SESSION_ACTIVITIES(" .
"F_ACTION_DT, F_SESSION_ID, F_SESSION_IP_ADDRESS, " .
"F_PAGE_REQUESTED, F_PAGE_REQUEST_PARAMS," .
"F_REQUEST_METHOD, F_PAGE_ACTION, F_IS_HTTPS_IND, F_IS_LOGGED_IN_IND, F_USER_KEY)" .
"Values (?,?,?,?,?,?,?,?,?,?)");
$_InsertSQL->bindParam(1, $this->Action_Dt );
$_InsertSQL->bindParam(2, $this->Session_Id );
$_InsertSQL->bindParam(3, $this->Session_IP_Address );
$_InsertSQL->bindParam(4, $this->Page_Requested );
$_InsertSQL->bindParam(5, $this->Page_Request_Params );
$_InsertSQL->bindParam(6, $this->Request_Method );
$_InsertSQL->bindParam(7, substr(trim($xPageAction),0,32));
$_InsertSQL->bindParam(8, $this->Is_Https_Ind );
$_InsertSQL->bindParam(9, $this->Is_Logged_In_Ind );
$_InsertSQL->bindParam(10, $this->User_Key );
try {
$objDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$objDb->beginTransaction();
$_InsertSQL->execute();
$objDb->commit();
unset($objDb);
unset($objConnect);
} catch (Exception $e) {
$objDb->rollBack();
unset($objDb);
echo "Failed: " . $e->getMessage();
}
}
}
?>
The issue seems to be in your clsSession class. This is using &. Since the session object is serialized these references aren't stored correctly. Try removing these (i.e. change UpdateSessionClassData and UpdateSession to remove the & from parameters) and see if this sorts the issue.
to start, put session_start(); before require_once and add var_dump($_SESSION) for debug.
Related
Something may be wrong with my logic or the hosting server because when I tried it locally it works flawlessly!! however, when I upload it always execute the second statement no matter what the value of applicant_email_activated is??
It is driving me crazy please help!
<?php
// Santize the provided inputs
$applicant_email = filter_var(stripAndCleanHTML($_GET['applicant_email']), FILTER_SANITIZE_EMAIL); # santize the email
$applicant_token = stripAndCleanHTML($_GET['applicant_token']); # santize the token
/**************** Find the applicant that has the same email *******************/
$database_connection = Database::database_connect();
$find_email_query = $database_connection->prepare('SELECT * FROM applicants WHERE applicant_email = :applicant_email && applicant_token = :applicant_token LIMIT 1');
$find_email_query->execute(['applicant_email' => $applicant_email, 'applicant_token' => $applicant_token]);
if ($find_email_query->errorCode() > 0) {
if (DEBUG === true) {
echo 'There was an issue in searching for the email Big Boss: <br>';
print_r($find_email_query->errorInfo());
die();
} else {
header('location:../404.shtml', true, 404);
die();
}
}
$applicants = $find_email_query->fetchAll();
foreach ($applicants as $applicant) {
$applicant_username = (string) stripAndCleanHTML($applicant['applicant_username']);
$applicant_password = (string) stripAndCleanHTML($applicant['applicant_password']);
$applicant_name = (string) stripAndCleanHTML($applicant['applicant_name']);
$applicant_phone = (string) stripAndCleanHTML($applicant['applicant_phone']);
$applicant_birthdate = (string) stripAndCleanHTML($applicant['applicant_birthdate']);
$applicant_city = (string) stripAndCleanHTML($applicant['applicant_city']);
$applicant_country = (string) stripAndCleanHTML($applicant['applicant_country']);
$applicant_major = (string) stripAndCleanHTML($applicant['applicant_major']);
$applicant_major_type = (string) stripAndCleanHTML($applicant['applicant_major_type']);
$applicant_exp_years = (string) stripAndCleanHTML($applicant['applicant_exp_years']);
$applicant_cv = (string) stripAndCleanHTML($applicant['applicant_cv']);
$applicant_email_activated = (int) stripAndCleanHTML($applicant['applicant_email_activated']);
}
if ($applicant_email_activated === 1) {
include '../../includes/job_app/email_has_been_activated.inc.php';
} elseif ($applicant_email_activated === 0) {
include '../../includes/job_app/email_confirmed.php';
}
?>
this is the function I used to clean the value:
function stripAndCleanHTML($to_clean)
{
return htmlspecialchars(strip_tags(stripslashes(trim($to_clean))));
}
and this is the Database class:
class Database
{
private const DB_HOST = 'domain.com';
private const DB_NAME = 'ats';
private const DB_CHARSET = 'utf8';
private const DB_USER = 'public_user';
private const DB_PASS = '1F#kaH$!q5r2as';
public static function database_connect()
{
try {
// setting DSN (Data Source Name)
$dsn = 'mysql:host=' . Database::DB_HOST . ';' . 'dbname=' . Database::DB_NAME . ';' . 'charset=' . Database::DB_CHARSET;
// creating a PDO (PHP Data Object) instance
$pdo = new PDO($dsn, Database::DB_USER, Database::DB_PASS);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $pdo;
} catch (Exception $e) {
if (DEBUG === true) {
echo $e->getMessage().'<br>';
die();
} else {
die();
}
}
return $db_info;
}
}
It did work after I removed the (int) and put the compersion numbers into single quotes!! crazy right!!?
I guess the server on the hosting company handles PHP in a peculiar manner!! or maybe I have pumped up the app with a lot of stripping non-sense as some of you would agree, nonetheless, I have done it and I could go home and sleep knowing my baby app is safe and sound!
A huge thank you for the tips and mentoring, have a good day! and do not forget to be awesome.
I have a php database class for managing all my database queries:
class DatabaseConnection()
{
private $link;
public $filter;
public function log_db_errors( $error, $query )
{
if( MY_DEBUG )
{
echo $message;
}
}
public function __construct()
{
global $connection;
mb_internal_encoding( 'UTF-8' );
mb_regex_encoding( 'UTF-8' );
$this->link = new mysqli( MY_HOST, MY_USER, MY_PASS, MY_DB );
$this->link->set_charset( "utf8" );
if( $this->link->connect_errno )
{
$this->log_db_errors( "Connect failed", $this->link->connect_error );
echo 'Server error. Please try again sometime. DB';
exit();
}
}
public function __destruct()
{
$this->disconnect();
}
public function filter( $data )
{
if( !is_array( $data ) )
{
$data = trim( htmlentities( $data ) );
$data = $this->link->real_escape_string( $data );
}
else
{
$data = array_map( array( 'DB', 'filter' ), $data );
}
return $data;
}
public function query( $query )
{
$full_query = $this->link->query( $query );
if( $this->link->error )
{
$this->log_db_errors( $this->link->error, $query );
$full_query->free();
return false;
}
else
{
$full_query->free();
return true;
}
}
public function my_table_exists_create( $table, $variables = array() ) {
$check = $this->link->query("SELECT * FROM '$table' LIMIT 1");
if( $check ) return true;
else {
if( empty( $variables ) ) {
return false;
exit;
}
$sql = "CREATE TABLE IF NOT EXISTS ". $table;
$fields = array();
$values = array();
foreach( $variables as $field ) {
$fields[] = $field; //$values[] = "'".$value."'";
}
$fields = ' (' . implode(', ', $fields) . ')';
$sql .= $fields;
$query = $this->link->query( $sql );
if( $this->link->error ) {
$this->log_db_errors( $this->link->error, $sql );
return false;
}
else return true;
}
}
public function my_num_rows( $query )
{
$num_rows = $this->link->query( $query );
if( $this->link->error )
{
$this->log_db_errors( $this->link->error, $query );
return $this->link->error;
}
else
{
return $num_rows->num_rows;
}
}
public function exists( $table = '', $check_val = '', $params = array() )
{
if( empty($table) || empty($check_val) || empty($params) )
{
return false;
exit;
}
$check = array();
foreach( $params as $field => $value )
{
if( !empty( $field ) && !empty( $value ) )
{
if( $this->db_common( $value ) )
{
$check[] = "$field = $value";
}
else
{
$check[] = "$field = '$value'";
}
}
}
$check = implode(' AND ', $check);
$rs_check = "SELECT $check_val FROM ".$table." WHERE $check";
$number = $this->my_num_rows( $rs_check );
if( $number === 0 )
{
return false;
}
else
{
return true;
}
exit;
}
public function disconnect()
{
$this->link->close();
}
}
I use this class to manage all my queries, like insert to the database :
$database = new DatabaseConnection();
$Item_Details = array(
'item_title' => trim($_POST['title']),
'item_content' => trim($_POST['content']),
'item_updated' => date('Y-m-d H:i:s'),
'item_updatedby' => $my_loginid,
);
$where_clause = array('itemid' => $itemid);
$updated = $database->as_update( 'my_item', $Item_Details , $where_clause, 1 );
Now I need to know I can use this class without having a lot of connections that can slow down connection to the server which leads to timeout and having too many connection. I thought I could use a global variable
function my_constant_initialize()
{
global $databasecon;
$databasecon = new DatabaseConnection();
return $databasecon;
}
So please advice how to avoid too many connections. Also as well as tell whether it is necessary to instanciate the database class for every query or I can just call it once because I have used a lot of Include and require functions in my php code.
Reaching the MySQL database connection limit is hard in OOP PHP because it destructs the connection object if the script is finished. Just to be safe, have a destruct function in your class and unset the object at the end of the script. If you are really worried about reaching the connection cap you can go into MySQL and modify the max_connection_limit from I think 1000 to higher and increase the buffer pool.
Additionally you might look into switching languages to like Java which has a technique called "connection pooling." Works better than PHP's version. No this is not the same as p_connect or whatever it is in PHP.
At least you don't have to initiate the connection every time you are calling your class.
To see how you could use your database class without having to instantiate it every time, we would need to see some more of your code. The already mentioned singleton pattern is the way to go, but it is hard to judge if it would really improve your code without knowing how you are actually programming.
This shows an implementation of your class as singleton:
class DatabaseConnection {
protected static $instance = null;
private $link;
public $filter;
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self;
}
return self::$instance;
}
protected function __construct() {
global $connection;
mb_internal_encoding( 'UTF-8' );
mb_regex_encoding( 'UTF-8' );
$this->link = new mysqli( MY_HOST, MY_USER, MY_PASS, MY_DB );
$this->link->set_charset( "utf8" );
if( $this->link->connect_errno )
{
$this->log_db_errors( "Connect failed", $this->link->connect_error );
echo 'Server error. Please try again sometime. DB';
exit();
}
}
protected function __clone() {
}
// add your other methods
}
You can call the connection by using
$databasecon = DatabaseConnection::getInstance();
By implementing it this way, when you call getInstance it checks if the connection has already been initialised so you can reuse it.
You set the __construct() as protected so the class can not be called without using the getInstance() method, same for __clone().
This is my code
class WcfClient {
public $wcfClient = null;
public $user = null;
public function __construct(){
if(isset($_SESSION['APIClient']) && $_SESSION['APIClient'] != null){
$this->wcfClient = $_SESSION['APIClient'];
}
}
public function __destruct(){
}
// Authanticate
private function Authenticate(){
global $_sogh_soapUrl, $_isDebug, $_sogh_header;
$wcargs = array();
$consumerAuthTicket = null;
if($this->wcfClient == null){
$args = array(
'clubname'=>'Wellness Institute at Seven Oaks',
'consumerName'=>'api',
'consumerPassword'=>'api'
);
try{
$wcargs = array(
'soap_version'=>SOAP_1_2
);
if($_isDebug){
$wcargs = array(
'soap_version'=>SOAP_1_2,
'proxy_host'=>"192.168.0.1",
'proxy_port'=>8080
);
}
// Connect to the API with soapclient
$soapAPIClient = new SoapClient($_sogh_soapUrl, $wcargs);
$response = $soapAPIClient->AuthenticateClubConsumer($args);
if(isset($response->AuthenticateClubConsumerResult)){
if(isset($response->AuthenticateClubConsumerResult->IsException) && $response->AuthenticateClubConsumerResult->IsException == true){
// some error occur
$this->wcfClient = null;
$_SESSION['APIClient'] = $this->wcfClient;
} else{
// set consumer ticket
$consumerAuthTicket = $response->AuthenticateClubConsumerResult->Value->AuthTicket;
// $loginData = $responseCode->ReturnValueOfConsumerLoginData;
$headers = array();
$headers[] = new SoapHeader($_sogh_header, "ConsumerAuthTicket", $consumerAuthTicket);
$soapAPIClient->__setSoapHeaders($headers);
// add to session
$this->wcfClient = $soapAPIClient;
$_SESSION['APIClient'] = $this->wcfClient;
}
}
} catch(SoapFault $fault){
$this->error('Fault: ' . $fault->faultcode . ' - ' . $fault->faultstring);
} catch(Exception $e){
$this->error('Error: ' . $e->getMessage());
}
}
return $this->wcfClient;
}
I store the soap client object in $_SESSION['APIClient'], but second times when run some data has been changed in session, I am use this class in drupal 7, I want to save the time using session, because authenticating takes long time.
Please help
Thank in advance
Can someone help why my JSON file can't show? I beginner for JSON. This is my code, its only show blank document. I am learning this tutorial from this website http://contohprogramandroid.blogspot.com/2013/10/contoh-program-android-aplikasi-wisata.html. thank you so much.
this my image when running the code.
//this is the code webservice.php
<?php
class Database {
private $host = "localhost";
private $user = "root";
private $pass = "";
private $db = "wisata_jogja";
private $conn;
// constructor
function __construct() {
try{
$this->conn = new PDO( "mysql:host=".$this->host.";dbname=".$this->db, $this->user, $this->pass );
}catch( PDOException $e ) {
echo "error pdo $e";
}
}
public function showAllData( $table ) {
$sql ="SELECT * FROM $table";
$q = $this->conn->query( $sql ) or die( "Failed !!" );
while ( $r = $q->fetch( PDO::FETCH_ASSOC ) ) {
$data[] = $r;
}
return $data;
}
}
$database = new Database();
$response = array();
if ( isset( $_GET['get'] ) && $_GET['get']=='lokasi' ) {
$response['location'] = array();
foreach ( $database->showAllData( 'lokasi' ) as $value ) {
$kode = array();
extract( $value );
$kode['id'] = $id;
$kode['nama'] = $nama;
$kode['alamat'] = $alamat;
$kode['gambar'] = $gambar;
$kode['lat'] = $lat;
$kode['lng'] = $lng;
array_push( $response['location'], $kode );
}
echo json_encode( $response );
}
?>
Your condition to output is this:
if ( isset( $_GET['get'] ) && $_GET['get']=='lokasi' ) {
Thus, the script won't output any JSON since condition is not met.
From your screenshot it is clear your are missing the GET parameters.
In your browser add the parameter to the url:
http://localhost/wisata/webservice.php?get=lokasi
It's always good to take alternative action when condition is not true.
You should always echo something just so you know what is going on:
if ( isset( $_GET['get'] ) && $_GET['get']=='lokasi' ) {
//..............
echo json_encode( $response );
}else{
echo "cannot output JSON data: parameter is missing!!;
}
Are you sure that you pass the GET variable "lokasi" to your script ?
Otherwise, it would not go through the if condition
if(isset($_GET['get'] ) && $_GET['get']=='lokasi')
You can check this by trying to dump the variable or any foobar data inside the if condition to verify your code goes that far, for instance :
if(isset($_GET['get'] ) && $_GET['get']=='lokasi') {
$response['location'] = array();
$myTest = array('test');
var_dump($myTest); // Should display something on screen
// The rest of your code here
Im trying to make Cassandra run with PHP on Windows 7 at the moment.
I installed cassandra and thrift...
When I call the cassandra-test.php, I get the following error:
( ! ) Fatal error: Call to undefined method
CassandraClient::batch_insert() in
C:\xampp\htdocs\YiiPlayground\cassandra-test.php on line 75
Call Stack
# Time Memory Function Location
1 0.0014 337552 {main}( ) ..\cassandra-test.php:0
2 0.0138 776232 CassandraDB->InsertRecord(
) ..\cassandra-test.php:304
The cassandra-test.php looks as follows:
<?php
// CassandraDB version 0.1
// Software Projects Inc
// http://www.softwareprojects.com
//
// Includes
$GLOBALS['THRIFT_ROOT'] = 'C:/xampp/htdocs/Yii/kallaspriit-Cassandra-PHP-Client-Library/thrift';
//$GLOBALS['THRIFT_ROOT'] = realpath('E:/00-REGIESTART/Programme/Cassandra/thrift');
require_once $GLOBALS['THRIFT_ROOT'].'/packages/cassandra/Cassandra.php';
require_once $GLOBALS['THRIFT_ROOT'].'/packages/cassandra/cassandra_types.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TFramedTransport.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
class CassandraDB
{
// Internal variables
protected $socket;
protected $client;
protected $keyspace;
protected $transport;
protected $protocol;
protected $err_str = "";
protected $display_errors = 0;
protected $consistency = 1;
protected $parse_columns = 1;
// Functions
// Constructor - Connect to Cassandra via Thrift
function CassandraDB ($keyspace, $host = "127.0.0.1", $port = 9160)
{
// Initialize
$this->err_str = '';
try
{
// Store passed 'keyspace' in object
$this->keyspace = $keyspace;
// Make a connection to the Thrift interface to Cassandra
$this->socket = new TSocket($host, $port);
$this->transport = new TFramedTransport($this->socket, 1024, 1024);
$this->protocol = new TBinaryProtocolAccelerated($this->transport);
$this->client = new CassandraClient($this->protocol);
$this->transport->open();
}
catch (TException $tx)
{
// Error occured
$this->err_str = $tx->why;
$this->Debug($tx->why." ".$tx->getMessage());
}
}
// Insert Column into ColumnFamily
// (Equivalent to RDBMS Insert record to a table)
function InsertRecord ($table /* ColumnFamily */, $key /* ColumnFamily Key */, $record /* Columns */)
{
// Initialize
$this->err_str = '';
try
{
// Timestamp for update
$timestamp = time();
// Build batch mutation
$cfmap = array();
$cfmap[$table] = $this->array_to_supercolumns_or_columns($record, $timestamp);
// Insert
$this->client->batch_insert($this->keyspace, $key, $cfmap, $this->consistency);
// If we're up to here, all is well
$result = 1;
}
catch (TException $tx)
{
// Error occured
$result = 0;
$this->err_str = $tx->why;
$this->Debug($tx->why." ".$tx->getMessage());
}
// Return result
return $result;
}
// Insert SuperColumn into SuperColumnFamily
// (Equivalent to RDMBS Insert record to a "nested table")
function InsertRecordArray ($table /* SuperColumnFamily */, $key_parent /* Super CF */,
$record /* Columns */)
{
// Initialize
$err_str = '';
try
{
// Timestamp for update
$timestamp = time();
// Build batch mutation
$cfmap = array();
$cfmap[$table] = $this->array_to_supercolumns_or_columns($record, $timestamp);
// Insert
$this->client->batch_insert($this->keyspace, $key_parent, $cfmap, $this->consistency);
// If we're up to here, all is well
$result = 1;
}
catch (TException $tx)
{
// Error occured
$result = 0;
$this->err_str = $tx->why;
$this->Debug($tx->why." ".$tx->getMessage());
}
// Return result
return $result;
}
// Get record by key
function GetRecordByKey ($table /* ColumnFamily or SuperColumnFamily */, $key, $start_from="", $end_at="")
{
// Initialize
$err_str = '';
try
{
return $this->get($table, $key, NULL, $start_from, $end_at);
}
catch (TException $tx)
{
// Error occured
$this->err_str = $tx->why;
$this->Debug($tx->why." ".$tx->getMessage());
return array();
}
}
// Print debug message
function Debug ($str)
{
// If verbose is off, we're done
if (!$this->display_errors) return;
// Print
echo date("Y-m-d h:i:s")." CassandraDB ERROR: $str\r\n";
}
// Turn verbose debug on/off (Default is off)
function SetDisplayErrors($flag)
{
$this->display_errors = $flag;
}
// Set Consistency level (Default is 1)
function SetConsistency ($consistency)
{
$this->consistency = $consistency;
}
// Build cf array
function array_to_supercolumns_or_columns($array, $timestamp=null)
{
if(empty($timestamp)) $timestamp = time();
$ret = null;
foreach($array as $name => $value) {
$c_or_sc = new cassandra_ColumnOrSuperColumn();
if(is_array($value)) {
$c_or_sc->super_column = new cassandra_SuperColumn();
$c_or_sc->super_column->name = $this->unparse_column_name($name, true);
$c_or_sc->super_column->columns = $this->array_to_columns($value, $timestamp);
$c_or_sc->super_column->timestamp = $timestamp;
}
else
{
$c_or_sc = new cassandra_ColumnOrSuperColumn();
$c_or_sc->column = new cassandra_Column();
$c_or_sc->column->name = $this->unparse_column_name($name, true);
$c_or_sc->column->value = $value;
$c_or_sc->column->timestamp = $timestamp;
}
$ret[] = $c_or_sc;
}
return $ret;
}
// Parse column names for Cassandra
function parse_column_name($column_name, $is_column=true)
{
if(!$column_name) return NULL;
return $column_name;
}
// Unparse column names for Cassandra
function unparse_column_name($column_name, $is_column=true)
{
if(!$column_name) return NULL;
return $column_name;
}
// Convert supercolumns or columns into an array
function supercolumns_or_columns_to_array($array)
{
$ret = null;
for ($i=0; $i<count($array); $i++)
foreach ($array[$i] as $object)
{
if ($object)
{
// If supercolumn
if (isset($object->columns))
{
$record = array();
for ($j=0; $j<count($object->columns); $j++)
{
$column = $object->columns[$j];
$record[$column->name] = $column->value;
}
$ret[$object->name] = $record;
}
// (Otherwise - not supercolumn)
else
{
$ret[$object->name] = $object->value;
}
}
}
return $ret;
}
// Get record from Cassandra
function get($table, $key, $super_column=NULL, $slice_start="", $slice_finish="")
{
try
{
$column_parent = new cassandra_ColumnParent();
$column_parent->column_family = $table;
$column_parent->super_column = $this->unparse_column_name($super_column, false);
$slice_range = new cassandra_SliceRange();
$slice_range->start = $slice_start;
$slice_range->finish = $slice_finish;
$predicate = new cassandra_SlicePredicate();
$predicate->slice_range = $slice_range;
$resp = $this->client->get_slice($this->keyspace, $key, $column_parent, $predicate, $this->consistency);
return $this->supercolumns_or_columns_to_array($resp);
}
catch (TException $tx)
{
$this->Debug($tx->why." ".$tx->getMessage());
return array();
}
}
// Convert array to columns
function array_to_columns($array, $timestamp=null) {
if(empty($timestamp)) $timestamp = time();
$ret = null;
foreach($array as $name => $value) {
$column = new cassandra_Column();
$column->name = $this->unparse_column_name($name, false);
$column->value = $value;
$column->timestamp = $timestamp;
$ret[] = $column;
}
return $ret;
}
// Get error string
function ErrorStr()
{
return $this->err_str;
}
}
// Initialize Cassandra
$cassandra = new CassandraDB("SPI");
// Debug on
$cassandra->SetDisplayErrors(true);
// Insert record ("Columns" in Cassandra)
$record = array();
$record["name"] = "Mike Peters";
$record["email"] = "mike at softwareprojects.com";
if ($cassandra->InsertRecord('mytable', "Mike Peters", $record)) {
echo "Record (Columns) inserted successfully.\r\n";
}
// Print record
$record = $cassandra->GetRecordByKey('mytable', "Mike Peters");
print_r($record);
?>
Any ideas on this, how to fix this?
Thanks a lot!
You really don't want to do Thrift by hand if you can avoid it. Take a look at phpcassa library:
https://github.com/thobbs/phpcassa
Oh, and in the above, looks like you want 'batch_mutate' not 'batch_insert' on ln. 75. That method changed names in versions of cassandra > 0.6.x