AmfPHP 2.0 running on PHP 7 & PDO - mysql

AmfPHP 2.0 running on Nginx and PHP 7.0 (FPM), PDO is used as database.
As many users log in to the game, the CPU increases immediately to 100% on all 4 cores due to MySQL. If there are fewer players, the process calms down again and the CPU drops.
Code snippet of PDO connection:
class Database extends PDO {
public static function getConnection() {
$connectionString = sprintf("mysql:dbname=%s;host=%s;charset=utf8", MYSQL_DB, MYSQL_HOST);
try {
$pdo = new PDO($connectionString, MYSQL_USER, MYSQL_PASS);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch(PDOException $e) {
$error = date("Y-m-d g:i:s a T") . "\Database::getConnection\tError: (" . $e->getCode . ") " . $e->getMessage;
throw new Exception($error);
}
}
// Example
public static function Test($arg) {
try {
$pdo = Database::getConnection();
$stmt = $pdo->prepare("select * from xx where xx = :xx");
$stmt->bindParam(":xx", $arg, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($stmt->rowCount() > 0) {
// execute my code
}
} catch(PDOException $e) {
$error = date("Y-m-d g:i:s a T") . "\Database::Test\tError: (" . $e->getCode . ") " . $e->getMessage;
throw new Exception($error);
}
}
}
For further questions I am at any time available.

Related

How to retrieve composite column from Cassandra table in PHP

I have a CassandraHandler that retrieves the queries in rows
class CassandraHandler
{
private $keyspace = 'blabla'; //default is oyvent
private $cluster = NULL;
private $session = NULL;
function __construct(){
$this->cluster = \Cassandra::cluster()
->build(); // connects to localhost by default
$this->session = $this->cluster->connect($this->keyspace);
}
/**
* #return Rows
*/
public function execute($query){
$statement = new \Cassandra\SimpleStatement($query);
$result = $this->session->execute($statement);
return $result;
}
}
When I use for normal columns it's fine but I can't get my photo column in php
I created the column like this
photos frozen<set<map<text,text>>>
my json example
{{"urllarge": "1.jpg", "urlmedium": "2.jpg"},
{"urllarge": "3.jpg", "urlmedium": "4.jpg"}}
And here how can I use PHP to retrieve the composite columns?
$cassandraHandler = new CassandraHandlerClass();
$rows = $cassandraHandler->fetchLatestPosts($placeids, $limit);
foreach ($rows as $row) {
$tmp = array();
$tmp["userid"] = doubleval($row["userid"]);
$tmp["fullname"] = $row["fullname"];
$tmp["photos"] = $row["photos"] //????????
}
I know there is this documentation of the PHP driver https://github.com/datastax/php-driver
But I am a little confused.. I just need to get the json value like I get in cqlsh
You have two options to convert the composites into useable JSON:
Create a function to convert the deserialized/unmarshalled objects into JSON.
Retrieve the values from Cassandra as JSON.
Here is an example that demonstrates both options:
<?php
$KEYSPACE_NAME = "stackoverflow";
$TABLE_NAME = "retrieve_composites";
function print_rows_as_json($rows) {
foreach ($rows as $row) {
$set_count = 0;
echo "{\"photos\": [";
foreach ($photos = $row["photos"] as $photo) {
$map_count = 0;
echo "{";
foreach ($photo as $key => $value) {
echo "\"{$key}\": \"{$value}\"";
if (++$map_count < count($photo)) {
echo ", ";
}
}
echo "}";
if (++$set_count < count($photos)) {
echo ", ";
}
}
echo "]}" . PHP_EOL;
}
}
// Override default localhost contact point
$contact_points = "127.0.0.1";
if (php_sapi_name() == "cli") {
if (count($_SERVER['argv']) > 1) {
$contact_points = $_SERVER['argv'][1];
}
}
// Connect to the cluster
$cluster = Cassandra::cluster()
->withContactPoints($contact_points)
->build();
$session = $cluster->connect();
// Create the keypspace (drop if exists) and table
$session->execute("DROP KEYSPACE IF EXISTS {$KEYSPACE_NAME}");
$session->execute("CREATE KEYSPACE {$KEYSPACE_NAME} WITH replication = "
. "{ 'class': 'SimpleStrategy', 'replication_factor': 1 }"
);
$session->execute("CREATE TABLE ${KEYSPACE_NAME}.{$TABLE_NAME} ( "
. "id int PRIMARY KEY, "
. "photos frozen<set<map<text, text>>> )"
);
// Create a multiple rows to retrieve
$session->execute("INSERT INTO ${KEYSPACE_NAME}.{$TABLE_NAME} (id, photos) VALUES ( "
. "1, "
. "{{'urllage': '1.jpg', 'urlmedium': '2.jpg'}, "
. "{'urllage': '3.jpg', 'urlmedium': '4.jpg'}}"
. ")");
$session->execute("INSERT INTO ${KEYSPACE_NAME}.{$TABLE_NAME} (id, photos) VALUES ( "
. "2, "
. "{{'urllage': '21.jpg', 'urlmedium': '22.jpg'}, "
. "{'urllage': '23.jpg', 'urlmedium': '24.jpg'}}"
. ")");
// Select and print the unmarshalled data as JSON
$rows = $session->execute("SELECT photos FROM ${KEYSPACE_NAME}.{$TABLE_NAME}");
print_rows_as_json($rows);
// Select the data as JSON and print the string
$rows = $session->execute("SELECT JSON photos FROM ${KEYSPACE_NAME}.{$TABLE_NAME}");
foreach ($rows as $row) {
echo $row["[json]"] . PHP_EOL;
}
From the above example you can see that selecting the data as JSON involves less code for your application while also moving the processing onto the server. This probably the preferred choice for your application needs.
NOTE: This example is using v1.3.0 of the DataStax PHP driver which added support to pass a query strings directly to Session::execute() and Session::executeAsync(). If you are using an earlier version you will need to convert all query strings to Cassandra\Statement objects before passing to $session->execute(...).

Zend error Connection

I have a problem with my code, the first code is like
<?php
require_once('zend/json.php');
require_once('zend/db.php');
//require_once 'Zend/Db/Adapter/Pdo/pgsql.php';
class jsonvi
{
protected $_db;
public function _koneksi ()
{
try
{
$this->_db = zend_db::factory('PDO_PGSQL',array(
'host'=>'localhost',
'username'=>'stet',
'password'=>'test',
'dbname'=>'test'
));
return $this->_db;
}
catch(zend_db_exception $e)
{
return $e->getmessage();
}
}
public function getdata()
{
$db = $this->_koneksi();
try
{
$sql = "select * from info ";
$da = $db->fetchall($sql);
$num = count($da);
for ($a=0;$a<$num;$a++)
{
$data = $db->fetchall($sql);
return $data;
}
}
catch (zend_db_exception $e)
{
return $e->getmessage();
}
}
}
$view = new jsonvi();
$view = $view->getdata();
echo zend_json::encode($view);
?>
and it works well, but I want to make it like
<?php
include ('table.php');
include ('config.php');
require_once('zend/json.php');
require_once('zend/db.php');
require_once 'Zend/Db/Adapter/Pdo/pgsql.php';
class jsonvi
{
protected $_db;
public function _koneksi ()
{
try
{
$this->_db = zend_db::factory('PDO_PGSQL',array(
'host'=>$dbhost,
'username'=>$dbuser,
'password'=>$dbpass,
'dbname'=>$dbdb
));
return $this->_db;
}
catch(zend_db_exception $e)
{
return $e->getmessage();
}
}
public function getdata()
{
$db = $this->_koneksi();
try
{
$sql = "select * from ".$table;
$da = $db->fetchall($sql);
$num = count($da);
for ($a=0;$a<$num;$a++)
{
$data = $db->fetchall($sql);
return $data;
}
}
catch (zend_db_exception $e)
{
return $e->getmessage();
}
}
}
$view = new jsonvi();
$view = $view->getdata();
echo zend_json::encode($view);
?>
I don't know whats wrong with this code, I need help.
the error message Notice: Undefined variable: dbdb in C:\wamp....
The config.php is only have code like $dbpass = 'test'; and like that, I'm creating a simple web and I want to make my code to other database and aplikasi, so I only changed the config.php and the table.php
for the table.php maybe will work if the config.php work.
Thanks.
You are using a class and not paying attention to variable scope.
I understand you have variables with values for the DB connection in that config.php file. Although these variables are available inside the script file with the include they are NOT available and accessible inside your class. The only difference would be any constants with define (or variables inside a global which is not a good idea).
You could create a config class inside the config.php and set the values as properties then instantiate that class inside your _koneksi method. And then you would use a require_once instead of the include.
UPDATE
So here's an example that is similar to your file where your include ('config.php'); is essentially the same as declaring your variables directly before the class begins.
// variable defined outside the class
$foo = 'foo';
class demo
{
public $bar = 'bar';
function test()
{
$foobar = 'foobar';
echo 'Class property $bar is:' . $this->bar . PHP_EOL;
echo 'Local variable $foobar is:' . $foobar . PHP_EOL;
}
function run()
{
if (isset($foo)) {
echo 'Global variable $foo is:' . $foo . PHP_EOL;
} else {
// This is where you have your problem.
// Variables from outside the class are not available.
echo 'Global variable $foo not found' . PHP_EOL;
}
}
}
$demo = new demo();
$demo->test(); // Class property $bar is:bar
// Local variable $foobar is:foobar
$demo->run(); // Global variable $foo not found
echo 'Variable $foo is: ' . $foo . PHP_EOL; // Class property $bar is:bar

Mysql Clone user account from database

I have a database with aproximately 200 tables. I want to clone a certain user-account in this database. Is this possible in mysql?
With cloning I mean to create a new user with the same 'settings' as the user with id 14.
A quick google search reveals that you in fact can do this. There is a utility called " "mysql user clone", that lets you surprisingly clone a user for mysql.
If you check out the manual I'm sure it provides you with great tips about how to use it, for instance, this quote:
EXAMPLES
To clone joe as sam and sally with passwords and logging in as root on the local machine, use this command:
$ mysqluserclone --source=root#localhost \
--destination=root#localhost \
joe#localhost sam:secret1#localhost sally:secret2#localhost
# Source on localhost: ... connected.
# Destination on localhost: ... connected.
# Cloning 2 users...
# Cloning joe#localhost to user sam:secret1#localhost
# Cloning joe#localhost to user sally:secret2#localhost
# ...done.
since it appears #Nanne's approach, mysqluserclone is EOL / not supported by Oracle, i wrote a similar utility in PHP, usage:
<?php
$db = new \PDO("mysql:host={$db_creds->dbhost};dbname={$db_creds->dbname};charset=utf8mb4;port=" . $db_creds->dbport, $db_creds->superuser_user, $db_creds->superuser_pass, array(
\PDO::ATTR_EMULATE_PREPARES => false,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC
));
Mysqluserclone::clone_account($db, "original username", "cloned username");
and this part of the code may be of particular interest:
if (0) {
echo "the following SQLs will clone this account:\n";
echo implode("\n\n", $sqls_for_cloning) . "\n\n";
die();
}
<?php
class Mysqluserclone{
private function __construct(){
// by making this private, we ensure nobody try to instantiate us.
}
public static function clone_account(\PDO $db_connected_as_superuser, string $original_name, string $clone_name): void
{
$db = $db_connected_as_superuser;
$sqls_for_cloning = [];
$sql = "SELECT COUNT(*) FROM mysql.user WHERE User = " . $db->quote($clone_name);
if (0 !== $db->query($sql)->fetch(\PDO::FETCH_NUM)[0]) {
throw new \InvalidArgumentException("clone name already exists!");
}
$sql = "SELECT * FROM mysql.user WHERE User = " . $db->quote($original_name);
$current_user_one_for_each_host = $db->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
foreach ($current_user_one_for_each_host as $user_record) {
$user_record["User"] = $clone_name;
$sql = "INSERT INTO mysql.user SET \n";
foreach ($user_record as $name => $val) {
$sql .= self::mysql_quote_identifier($name) . " = " . self::mysql_quote_better($db, $val) . ",\n";
}
if (! empty($user_record)) {
$sql = substr($sql, 0, - strlen(",\n"));
}
$sql .= ";";
$sqls_for_cloning[] = $sql;
$sqls_for_cloning[] = "FLUSH PRIVILEGES;"; // YES this is required, otherwise you might get "grant not allowed to create accounts" errors
$grants_raw_sql = 'SHOW GRANTS FOR ' . $db->quote($original_name) . '#' . $db->quote($user_record['Host']) . ";";
try {
$grants_raw = $db->query($grants_raw_sql)->fetchAll(\PDO::FETCH_NUM);
} catch (\Throwable $ex) {
// somehow an empty grant table is a mysql error, not an empty rowset.. ignore it.
$grants_raw = [];
}
$grants_raw = array_map(function (array $arr): string {
if (count($arr) !== 1) {
throw new \LogicException("mysql layout for SHOW GRANTS has changed? investigate");
}
return $arr[0];
}, $grants_raw);
$original_name_as_identifier = self::mysql_quote_identifier($original_name);
$clone_name_as_identifier = self::mysql_quote_identifier($clone_name);
foreach ($grants_raw as $grant) {
if (false === strpos($grant, $original_name_as_identifier)) {
throw new \LogicException("original grant without original name as identifier? investigate");
}
$grant = self::str_replace_last($original_name_as_identifier, $clone_name_as_identifier, $grant);
$grant .= ";";
$sqls_for_cloning[] = $grant;
}
}
if (! empty($sqls_for_cloning)) {
$sqls_for_cloning[] = "FLUSH PRIVILEGES;";
}
if (0) {
echo "the following SQLs will clone this account:\n";
echo implode("\n\n", $sqls_for_cloning) . "\n\n";
die();
}
foreach ($sqls_for_cloning as $clone_sql) {
$db->exec($clone_sql);
}
}
private static function mysql_quote_identifier(string $identifier): string
{
return '`' . strtr($identifier, [
'`' => '``'
]) . '`';
}
private static function mysql_quote_better(\PDO $db, $value): string
{
if (is_null($value)) {
return "NULL";
}
if (is_int($value)) {
return (string) $value;
}
if (is_float($value)) {
return number_format($value, 10, '.', '');
}
if (is_bool($value)) {
return ($value ? "1" : "0");
}
return $db->quote($value);
}
private static function str_replace_last(string $search, string $replace, string $subject): string
{
$pos = strrpos($subject, $search);
if ($pos !== false) {
$subject = substr_replace($subject, $replace, $pos, strlen($search));
}
return $subject;
}
}

php mySQL Reliable way to check if a row matches a object class

I'm looking for a reliable way to check to see if a database entry matches an equivalent object class in php.
My current method is unreliable, I was hoping someone could supply a better solution.
My current solution seems to work most of the time, but out of around 600 entries, Ill randomly return about 5 entry's that are false positives.
Here is a simplified object class Im using
class MemberData
{
public $AccountID;
public $AccountName;
public $Website;
}
I then use reflection to loop through each property in the class and build my query string in the form of :
SELECT 1 WHERE `Property1` = value1 AND `Property2` = value2 AND `Property3` = value3
However like i mentioned, my code only works most of the time, and I cant pin down a common link on why Im getting false positives. It appears random.
Below is my full function.
//Pass in a member class and see if there is a matching database entry
function SqlDoRowValuesMatch($memberData)
{
//declare global vars into this scope
global $host, $user, $password, $dbname, $tableName;
//initiate the connection using mysqli
$databaseConnection = new mysqli($host, $user, $password, $dbname);
if($databaseConnection->connect_errno > 0)
{
die('Unable to connect to database [' . $databaseConnection->connect_error . ']');
}
//Get all the properties in the MemberData Class
//Using Reflection
$reflect = new ReflectionClass($memberData);
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
//Build the query string
$sql = "SELECT 1 FROM `".$tableName."` WHERE ";
foreach($props as $prop)
{
if(!is_null($prop->getValue($memberData)))
{
$sql = $sql.$prop->getName()."=".addSingleQuotes(addslashes($prop->getValue($memberData)))." AND ";
}
}
//Cut Trailing operator
$sql = rtrim($sql, " AND ");
if(!$result = $databaseConnection->query($sql))
{
die('There was an error creating [' . $databaseConnection->error . ']');
}
$databaseConnection->close();
//Check for a value of 1 to indicate that a match was found
$rowsMatch = 0;
while($row = $result->fetch_assoc())
{
foreach($row as $key => $value)
{
if($value == 1)
{
$rowsMatch = 1;
break;
}
}
}
return $rowsMatch; //0 = false, 1 = true
}

query function in cake php

I am writing code in php to basically 'map' data from a mySQL database to another database. I am using the code as follows:
$results = $this->query("select PT_FS_DATA_ID from PATIENT_FLOWSHEET_DATA where
DT_LAST_UPDATED_TIME = (select top 1 DT_LAST_UPDATED_TIME from PATIENT_FLOWSHEET_DATA
order by DT_LAST_UPDATED TIME desc) group by PT_FS_DATA_ID;");
however, I am getting an error:
syntax error, unexpected T_VARIABLE, expecting T_FUNCTION
Everywhere I look this seems to be the correct syntax. Is there something I'm missing here?
I tried putting the controller in there as well $this->controllerName->query, but that didn't work either.
Full Code:
class CaExtraFlowsheetFields extends CaBase {
public $name = 'CaExtraFlowsheetFields';
/*
NOTE: This is to take all the fields in flowsheet and
maps their id's.
*/
//public $useTable = 'ANSWER_ENTRY';
public $useTable = 'PATIENT_FLOWSHEET_DATA';
public $primaryKey = 'PT_FS_DATA_ID';
protected function getPrimaryKeyValue(
$hospital_id,
$patient_id,
$admission_id = null
) {
return $patient_id;
}
//*CHANGE BEGIN*
$results = $this->query("select PT_FS_DATA_ID from PATIENT_FLOWSHEET_DATA where
DT_LAST_UPDATED_TIME = (select top 1 DT_LAST_UPDATED_TIME from PATIENT_FLOWSHEET_DATA
order by DT_LAST_UPDATED TIME desc) group by PT_FS_DATA_ID;");
protected $filedMethodMappings = array(
'Method_GO' => array(
CaBase::KEY_MAPPING_LOGIC_COMPLEXITY => CaBase::LEVEL2_COMPLEXITY,
CaBase::KEY_FIELD_LOGIC_NAME => 'wsMethod_GO',
);
//########################################################################//
//Note[]>Block[] //
//>Method that calls LookUpField for every field in flowsheet // //
//########################################################################//
public function wsMethod_GO ($params) {
foreach($results as $value){
$questionName = ''.$value;
$msg_prefix = $this->name . "::" . __FUNCTION__ . ": ". "arrivez-vouz" ;
$ret = $this->wsLookUpField($params,$questionName,$msg_prefix);
return $ret;
}
unset($value);
}
//########################################################################//
public function wsLookUpField($params,$questionName,$msg_prefix){
$arrayValues=array();
try{
$hospital_id = $params[Constants::KEY_HOSPITAL_ID];
$patient_id = $params[Constants::KEY_PATIENT_ID];
$admission_id = $params[Constants::KEY_ADMISSION_ID];
$msg_prefix = $this->name . "::" . __FUNCTION__ . ": ". "attendez-vouz: l'hopital= ".$hospital_id.
" patient= ".$patient_id." admission= ".$admission_id;
//shows info about given question name
$msg_prefix = "*!*!*!*Show me ---> ".$questionName." : ".$answer_entry_id.
" = aic: " .$answer_id_check;
$ret = array();
//now with needed fields, grab the A_NAME:
$params = array(
'conditions' => array(
$this->name . '.PID' => $patient_id,
$this->name . '.PT_FS_DATA_ID' => $questionName,
),
'order' => array(
$this->name . '.' . $this->primaryKey . ' DESC'
),
'fields' => array(
$this->name . '.FS_VALUE_TEXT',
)
);
$rs = $this->find('first', $params);
/* check to make sure $rs has received an answer from the query
and check to make sure this answer is a part of the most recent
database entries for this note */
if (false != $rs) {
try {
$msg = $msg_prefix . "Data obtained successfully."."<br>".$result;
$result = $rs;
$ret = WsResponse::getResponse_Success($msg, $result);
} catch (Exception $e) {
$msg = $msg_prefix . "Exception occurred.";
$ret = WsResponse::getResponse_Error($msg);
}
/*answer was not part of most recent database entries, meaning no
answer was given for this particular question the last time this
particular note was filled out. Message is given accordingly.*/
} else {
$msg = $msg_prefix . "/No answer given.";
$ret = WsResponse::getResponse_Error($msg);
}
} catch (Exception $e) {
$msg = $msg_prefix . "Exception occurred.";
$ret = WsResponse::getResponse_Error($msg);
}
return $ret;
}
Here is what you are doing:
class ABC {
$result = 'whatever';
}
You can't declare a variable there!
Code needs to be inside a method/function...
class ABC
{
public function wsMethod_GO ($params)
{
$result = 'whatever';
}
}