How to get redis key value with class function and init file - php

In my project, I use redis.
And I have a init file including ip port and port, so class Datasource is used for analying init file and connecting redis.
Here is class Datasource.php code with function getRedis() in it:
namespace common;
class Datasource {
public function __construct() {}
public static function getRedis($config_name = NULL, $server_region = 'default') {
global $config;
$redis_config = $config['redis'][$config_name];
if ($config_name && $redis_config && $server_region) {
$this->_config_name = $config_name;
$this->_redis_config = $redis_config;
$this->_server_region = $server_region;
try {
$this->_redis = new \Redis();
$this->_redis->connect($this->_redis_config[$server_region]['host'], $this->_redis_config[$server_region]['port']);
if($this->_redis_config[$server_region]['password'] && !$this->_redis->auth($this->_redis_config[$server_region]['password'])) {
$this->_redis = null;
}
} catch (Exception $e) {
$this->_redis = null;
}
} else {
$this->_redis = null;
}
return self::$this->_redis;
}
}// end of class Datasource
Here is init file code of redis.ini.php
<?php
$config['redis']['instance1'] = array(
'default' => array(
'host' => '127.0.0.1',
'port' => '6379',
'timeout' => 5,
'pconnect' => 1,
'password' => '',
)
);
$config['redis']['instance2'] = array(
'default' => array(
'host' => '127.0.0.1',
'port' => '6379',
'timeout' => 5,
'pconnect' => 1,
'password' => '',
)
);
Now I want to get xie value which is in redis, Here is my html code:
<body style="height:100%" >
<?php
include "o1ws1v/class/common/Datasource.php";
include 'o1ws1v/conf/redis.ini.php';
$redis_obj = common\Datasource::getRedis('instance1');
$value = $redis_obj->get("xie");
echo "get key xie is:".$value."\n";
?>
</body>
Actually, key xie should be zuo. The corrent result is a line : "get key xie is:zuo"
But it showed nothing, Who can help me?

You use $this in a static method, and you can't. Additionaly, you catch all Exceptions while connecting to Redis, so you can't know why it wasn't unsuccessful. You need to do two things:
Turning on PHP errors (for development only of course)
Don't catch the Exceptions while connecting, and if you do - then log / keep the Exception's message.
Try something like this:
<?php
namespace common;
class Datasource
{
private static $_redis, $_config_name, $_redis_config, $_server_region;
public static function getRedis($config_name = NULL, $server_region = 'default')
{
error_reporting(E_ALL);
ini_set("display_errors", true);
global $config;
$redis_config = $config['redis'][$config_name];
if (!$config_name || !$redis_config || !$server_region) {
throw new \Exception('$config_name or $redis_config or $server_region is not set');
}
if (!$redis_config[$server_region]['password']) {
throw new \Exception('Redis password is not set');
}
self::$_config_name = $config_name;
self::$_redis_config = $redis_config;
self::$_server_region = $server_region;
self::$_redis = new \Redis();
self::$_redis->connect(self::$_redis_config[$server_region]['host'], self::$_redis_config[$server_region]['port']);
if (!self::$_redis->auth(self::$_redis_config[$server_region]['password'])) {
throw new \Exception("Can't login to Redis. Check password");
}
return self::$_redis;
}
}
And the error displaying code is obviously not belong here, it's just for you to see if there are any errors temporarly.
Also, I would add a condition to see if Redis is already set, then return the connection. Otherwise you will make another connection every time you call getRedis method. Something like this:
public static function getRedis(...)
{
if (!self::$_redis) {
...
}
return self::$_redis;
}

Related

How to add my function and use it properly in controller?

I have 'sendsms' function which i used it in one of my controllers and worked fine. now what i need to know how i can make class reference of this code to use it in other controllers, instead of copy/paste whole code in all controllers.
In other Q/A they mentioned about only creating reference but i wanted to do it properly like using constructor or etc, not just doing things work, i want to do it like real-world project.
Here's the code in controller :
public function store(Request $request)
{
$this->validate($request,[
'title' => 'required|string|min:6',
'gametype' => 'required|string|min:3',
'description' => 'required|string|min:1|max:180',
'price' => 'required|numeric|min:4',
'buyyer_id' => 'required|numeric|min:1'
// 'seller_id' => 'required|numeric|min:1'
]);
// return RequestModel::create([
// 'title' => $request['title'],
// 'description' => $request['description'],
// 'gametype' => $request['gametype'],
// 'price' => $request['price'],
// 'buyyer_id' => $request['buyyer_id'],
// 'seller_id' => Auth::user()->id,
// ]);
//
$requestModel = new RequestModel;
// store
$requestModel->title = $request['title'];
$requestModel->description = $request['description'];
$requestModel->gametype = $request['gametype'];
$requestModel->price = $request['price'];
$requestModel->buyyer_id = $request['buyyer_id'];
$requestModel->seller_id = Auth::user()->id;
$requestModel->save();
return $this->sendSms($request['title'], $request['gametype']);
}
// I want to use this code in another class to use it in all controllers without copy/paste it.
function sendSms($reqid, $recgametype) {
//Send sms to getway
//implement later.
$otp_prefix = ':';
$response_type = 'json';
$textMSGATLAS = iconv("UTF-8", 'UTF-8//TRANSLIT',"req : ( " .$reqid. " ) for ( " .$recgametype. " ) submitted ");
ini_set("soap.wsdl_cache_enabled", "0");
try {
$client = new SoapClient("http://xxxx");
$user = "user";
$pass = "pass";
$fromNum = "+xxx";
$toNum = "+xxxx";
$messageContent = $textMSGATLAS;
$op = "send";
$client->SendSMS($fromNum,$toNum,$messageContent,$user,$pass,$op);
} catch (SoapFault $ex) {
echo $ex->faultstring;
}
}
I'm right now learning and I'm beginner at this so help to understand how to make it work properly. Thanks.
You can create a separate SMS class like :
<?php
namespace App;
class SMS {
private $reqid;
private $recgametype;
public function __construct($reqid, $recgametype)
{
$this->reqid = $reqid;
$this->recgametype = $recgametype;
}
public function send()
{
$otp_prefix = ':';
$response_type = 'json';
$textMSGATLAS = iconv("UTF-8", 'UTF-8//TRANSLIT',"req : ( " .$this->reqid. " ) for ( " .$this->recgametype. " ) submitted ");
ini_set("soap.wsdl_cache_enabled", "0");
try {
$client = new SoapClient("http://xxxx");
$user = "user";
$pass = "pass";
$fromNum = "+xxx";
$toNum = "+xxxx";
$messageContent = $textMSGATLAS;
$op = "send";
return $client->SendSMS($fromNum,$toNum,$messageContent,$user,$pass,$op);
} catch (SoapFault $ex) {
throw new \Exception('SMS sending failed')
}
}
}
And then inside controller or wherever you would need :
public function sendSms($reqid, $recgametype) {
$sms = new \App\SMS($reqid, $recgametype);
$sms->send();
}
You can also create custom exception like SMSSendingFailedException and throw it instead of standard \Exception inside send() function.
That will help you to send appropriate response in controller like :
public function sendSms($reqid, $recgametype) {
try{
$sms = new \App\SMS($reqid, $recgametype);
$sms->send();
return response()->json('message' => 'SMS sent successfully', 200);
}
catch(SMSSendingFailedException $e){
return response()->json('message' => 'SMS sending failed', 500);
}
}
Then to go one step further, you can use concept of laravel facade if you need it all over the project with a quick class alias.

How to connect to redis server with init file and no passwd

First, I have wrapper Datasource class for connecting redis server.
And I have a init file of ip port and passwd etc;
The content redis.ini.php file is:
<?php
$config['redis']['instance1'] = array(
'default' => array(
'host' => '127.0.0.1',
'port' => '6379',
'timeout' => 5,
'pconnect' => 1,
'password' => '',
)
);
$config['redis']['instance2'] = array(
'default' => array(
'host' => '127.0.0.1',
'port' => '6379',
'timeout' => 5,
'pconnect' => 1,
'password' => '',
)
);
And the code of class Datasource.php is:
<?php
namespace common;
class Datasource {
public static $config_name;
public static $server_region;
public static $redis_config;
public function __construct() {}
public static function getRedis($config_name = NULL, $server_region = 'default') {
self::$config_name=$config_name;
self::$server_region=$server_region;
global $config;
self::$redis_config = $config['redis'][$config_name];
if (self::$config_name && self::$redis_config && self::$server_region) {
try {
self::$redis = new \Redis();
self::$redis->connect(self::$redis_config[$server_region]['host'], self::$redis_config[$server_region]['port']);
} catch (Exception $e) {
self::$redis = null;
}
} else {
self::$redis = null;
}
return self::$redis_config[$server_region]['host'] ;
}
}
Now, I want to use this class in html code:
<body style="height:100%" >
<?php
include "o1ws1v/class/common/Datasource.php";
include 'o1ws1v/conf/redis.ini.php';
$redis_obj = common\Datasource::getRedis('instance1');
echo $redis_obj;
?>
</body>
But unlucky, I can not get corrent value:127.0.0.1 in html .
I have found that the problem was try{}catch{}, when i delete these code, it work fine.
//delete these code, it works fine
try {
self::$redis = new \Redis();
self::$redis->connect(self::$redis_config[$server_region]['host'], self::$redis_config[$server_region]['port']);
} catch (Exception $e) {
self::$redis = null;
}
I have asked one question one hour ago in stackoverflow, sorry about one more question. My boss claim me to solve this question today.
I have defined my redis server with no password for logging. It seems nothing wrong for connecting redis server, Who can help me?
I have solved this porblem
self::$redis = new \Redis();// it is wrong
$redis=new \Redis();//it is right

Pipedrive Class not found?

I am facing a strange error. I got a fairly simple piece of code yet it is constantly giving me error that class not found.
The error i am getting is
Fatal error: Class 'pipedriveintegrationConfig' not found in /home/preston/public_html/fullslate-pipedrive/index.php on line 4
Here is index.php
require_once 'config.php';
require_once pipedriveintegrationConfig::PHP_LIB;
require_once 'fullslate.php';
require_once 'pipedrive.php';
require_once 'fullslate-pipedrive.php';
pipedriveintegrationConfig::init();
if ($_SERVER['argc'] > 1) {
$action = $_SERVER['argv'][1];
} else
if (isset($_GET['action'])) {
$action = $_GET['action'];
}
if ($action) {
switch($action) {
case 'sync-clients':
$client = new pipedriveintegrationFullslatePipedrive(pipedriveintegrationFullslateConfig::toArray(), pipedriveintegrationPipedriveConfig::toArray());
$client->syncClients();
break;
default:
throw new CustomException('Unknown command line action: ', $action);
break;
}
} else {
if (file_exists(__DIR__ . '/test.php')) {
require_once __DIR__ . '/test.php';
}
}
Code for config.php is
namespace pipedriveintegration;
class PipedriveConfig{
const URL = 'https://api.pipedrive.com/v1';
const API_TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXX';
const STAGE_ID_NEW_PROSPECT = 1;
const STAGE_ID_CONSULTATION_SCHEDULED = 3;
public static
function toArray() {
return array('url' => self::URL, 'api_token' => self::API_TOKEN, 'stage_id_new_prospect' => self::STAGE_ID_NEW_PROSPECT, 'stage_id_consultation_scheduled' => self::STAGE_ID_CONSULTATION_SCHEDULED,);
}
}
class FullslateConfig{
const URL = 'https://slcguitar.fullslate.com/api';
const API_TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXx';
public static
function toArray() {
return array('url' => self::URL, 'api_token' => self::API_TOKEN,);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
class Config{
const PHP_LIB = 'PHPLib.php';
const USE_TIMESTAMP = false;
//'2014-12-15';
public static
function init() {
APP::init(array('mode' => 'development','log' => array('level' => Log::LEVEL_ALL, 'append' => true, 'limit' => 10,), 'curl' => array('log' => false, 'retry' => 3,),'temp' => array('path' => __DIR__, 'active' => true,),));
}
}
class PDEBUG{
const USE_FIDDLER = false;
}
Not sure wrong I am doing?
You need to change the require to:
require_once \pipedriveintegration\Config::PHP_LIB;
Your namespace is pipedriveintegration not pipedriveintegrationConfig. Also the constant is inside the class Config.
I don't know which PHP version are you using but I tested this in 5.6 and it works.
Please remove API tokens, and regenerate them in the application, by publishing API token you are giving access to your account to everyone.

CakePHP change DATABASE_CONFIG variables, based on user input for custom datasource

I am looking for a way to access and change the DATABASE_CONFIG variables, based on user input. Using CakePHP I created a custom datasource, based on the one provided in the docs, to access an external API. The API returns a JSON string containing the 12 most recent objects. I need to be able to change the page number in the API request to get the next 12 results, as well as accept a free text query entered by the user.
app/Config/Database.php
class DATABASE_CONFIG {
public $behance = array(
'datasource' => 'BehanceDatasource',
'api_key' => '123456789',
'page' => '1',
'text_query' => 'foo'
);
}
app/Model/Datasource/BehanceDataSource.php
App::uses('HttpSocket', 'Network/Http');
class BehanceDatasource extends DataSource {
public $description = 'Beehance datasource';
public $config = array(
'api_key' => '',
'page' => '',
'text_query' => ''
);
public function __construct($config) {
parent::__construct($config);
$this->Http = new HttpSocket();
}
public function listSources($data = null) {
return null;
}
public function describe($model) {
return $this->_schema;
}
public function calculate(Model $model, $func, $params = array()) {
return 'COUNT';
}
public function read(Model $model, $queryData = array(), $recursive = null) {
if ($queryData['fields'] === 'COUNT') {
return array(array(array('count' => 1)));
}
$queryData['conditions']['api_key'] = $this->config['api_key'];
$queryData['conditions']['page'] = $this->config['page'];
$queryData['conditions']['page'] = $this->config['text_query'];
$json = $this->Http->get('http://www.behance.net/v2/projects', $queryData['conditions']);
$res = json_decode($json, true);
if (is_null($res)) {
$error = json_last_error();
throw new CakeException($error);
}
return array($model->alias => $res);
}
}
Is there anyway to access and change the $behance array, or is there another way to go about accessing an external API with cakePHP that I am totally missing?

How to get a bootstrap resource in a controller plugin in Zend Framework

protected function _initDatabase()
{
$params = array(
'host' => '',
'username' => '',
'password' => '',
'dbname' => '',
);
$database = Zend_Db::factory('PDO_MYSQL', $params);
$database->getConnection();
return $database;
}
.
class App_Controller_Plugin_Test extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Http $request)
{
// how i get database?
}
}
You can always get a reference to the front controller:
$front = Zend_Controller_Front::getInstance();
From that you can get the bootstrap:
$bootstrap = $front->getParam("bootstrap");
From the bootstrap you can get bootstrap plugins:
if ($bootstrap->hasPluginResource("database")) {
$dbResource = $bootstrap->getPluginResource("database");
}
$db = $dbResource->getDatabase();
But that's a lot of extra plumbing!
Honestly, you'd be better off storing the database adapter object in the registry during your bootstrap:
protected function _initDatabase()
{
$params = array(
'host' => '',
'username' => '',
'password' => '',
'dbname' => '',
);
$database = Zend_Db::factory('PDO_MYSQL', $params);
$database->getConnection();
Zend_Registry::set("database", $database);
return $database;
}
Then you can get the database adapter anywhere:
Zend_Registry::get("database");
See also my answer to What is the “right” Way to Provide a Zend Application With a Database Handler
Too bad there's nothing like Zend_Controller_Action's getInvokeArg("bootstrap") in a plugin. You could always get the bootstrap reference through the front controller:
$db = Zend_Controller_Front::getInstance()->getParam("bootstrap")->getResource("database");
But what I usually do is
Zend_Registry::set('database', $database);
and then in your plugin:
try
{
$db = Zend_Registry::get('database');
}
catch (Zend_Exception $e)
{
// do stuff
}
Easier, and database can be retrieved pretty much anywhere in the application.
[I need to check this against some working code on another machine. I believe it's something like this...]
$db = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('db');
$db = Zend_Db_Table::getDefaultAdapter();

Categories