My Code is Like This
public function function1(){
$client = new Google_Client();
$client->setAccessToken('Some value');
}
public funnction function2(){
// Here I want to get the token using $client->getAccessToken()
}
How can use the same instance of class from function1 in function2? So I can use $client->getAccessToken() in function2
Simple Solution use global
<?php
$client;
function function1(){
global $client;
$client = new Google_Client();
$client->setAccessToken('Some value');
}
function function2(){
global $client;
$token=$client->getAccessToken();
}
?>
It's simple but not recommended. It's never a good Idea to use a global variables, we must avoid it as long as possible.
So there must be some other way,right ?
well yes use class
<?php
class ForClient {
private $client;
function __construct(){
$client = new Google_Client();
}
public function setToken($val){
$client->setAccessToken($val);
}
public function getToken(){
$token=$client->getAccessToken();
return $token;
}
}
$token_handler = new ForClient();
$token_handler->setToken(25);
$token=$token_handler->getToken();
?>
I changed the function names to make code more readable.
Related
Is there way to make Initialize fields option available for __construct() params to be also available for other methods?
I have a lot of classes which has methods setting data which are not __construct and writing all class params and $this->x = $x is pain.
I don't need making getters & setters from fields. I need exact same behavior as for constructors. I have method public function methodName($x, $y, $z) and I want params to be created for class.
Before
public function notConstructor($x, $y, $z) {
}
After
private $x;
private $y;
private $z;
public function notConstructor($x, $y, $z) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
Iam developing a website using codeigniter.I want to pass a particular data to all the controller.I searched and find it can be done by session like below.
$var = $this->session->userdata('passingdata');
But this data loses when history is cleared and when session expires.
Is there any other way to pass variable to all controllers.
You can try this
- create MY_Controller in application/core. it looks like
Class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('HomeModel');
$this->global_data['settings']= $this->HomeModel->getSettings();
}
function display_view($view, $local_data = array()) {
$data = array_merge($this->global_data, $local_data);
return $this->load->view($view, $data);
}}
then extend this controller in your all controller
your functions in your controller like
Class Home extends MY_Controller {
public function index() {
$data['title'] = 'test';
$this->display_view('home', $data);
}
}
My current model is somewhat like
class select extends CI_Model{
function __construct(){
parent::__construct();}
public function get_a(){
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table2','table1.id =
table2.id');
$this->db->where('x',1);
}
public function get_b(){
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table2','table1.id =
table2.id');
$this->db->where('x',2);
}
public function get_c(){
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table2','table1.id =
table2.id');
$this->db->where('x',3);
}
As you can see the same Join operation is repeating in all the three functions. Is there a way which I can just do this join once and use it with the where clause
And there are other questions. If that's possible is it efficient than this current method?
Repeating code is wasteful and avoidable. Here is one function that takes an argument to be used with where.
public function get_x($where){
$this->db
->select('*')
->from('table1')
->join('table2','table1.id = table2.id')
->where('x',$where);
}
if i understand you correct - you can do the following
class select extends CI_Model
{
public function __construct()
{
parent::__construct();
}
public function get_a()
{
$this->initializeBaseQuery();
$this->db->where('x',1);
}
public function get_b()
{
$this->initializeBaseQuery();
$this->db->where('x',2);
}
public function get_c()
{
$this->initializeBaseQuery();
$this->db->where('x',3);
}
private function initializeBaseQuery()
{
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table2','table1.id = table2.id');
}
}
You can try this solution for your problem :
Select modal file :
<?php
class Select extends CI_Model{
function __construct(){
parent::__construct();
}
public function get_selection($where = array()){
$this->db->select('*');
$this->db->from('table1');
$this->db->join('table2','table1.id = table2.id', 'left');
if(!empty($where)) {
foreach ($where as $key => $value) {
$this->db->where($key,$value);
}
}
$query_result = $this->db->get();
$result = $query_result->result();
return $result;
}
}
?>
Text Controller file :
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Test extends CI_Controller {
public function __construct() {
parent::__construct();
}
public function get_select(){
$where = array("x"=>"1"); // you can pass more than one key and value for condition.
$result =$this->select->get_selection($where);
echo "<pre>";
print_r($result);
exit;
}
}
}
?>
I Hope it will help you.
I am trying to create simple singleton in yii2 contoller. Maybe i misunderstood something about this pattern but i decide to try. So i have a CRUD. When i got one instance of that class in the db and i decide to update it, the $instance variable is empty(null). Is it because of the page reloading after the creation of the instance and that's why my static variable is set to null again? And is it even possible to make it like this or i am really, really on wrong way? Thank you in advance!
<?php
namespace backend\controllers;
use backend\models\DeliveryTime;
use yii\data\ActiveDataProvider;
use Yii;
class DeliveryTimeController extends \yii\web\Controller
{
public static $instance = null;
public function actionIndex()
{
$delivery = new ActiveDataProvider([
'query' => DeliveryTime::find()->where('id>0')
]);
return $this->render('index', ['delivery' => $delivery]);
}
public static function setInstance()
{
if(self::$instance == null){
self::$instance = new DeliveryTime();
}
return self::$instance;
}
public static function getInstance(){
return self::$instance;
}
public function actionCreate()
{
$delivery = DeliveryTimeController::setInstance();
if($delivery->load(Yii::$app->request->post()) && $delivery->save()){
self::$instance = $delivery;
return $this->redirect(['index']);
}
return $this->render('create', ['model' => $delivery]);
}
public function actionUpdate()
{
$delivery = DeliveryTimeController::getInstance();
if($delivery->load(Yii::$app->request->post()) && $delivery->save()){
return $this->render(['index']);
}
return $this->render('update', ['model' => $delivery]);
}
public function actionDelete(){
$delivery = DeliveryTimeController::getInstance();
if($delivery != null){
$delivery->delete();
return $this->redirect(['index']);
}
}
}
For design patterns i would recommend to check out
https://github.com/kamranahmedse/design-patterns-for-humans
https://github.com/edin/php-design-patterns (my github repo :)
For what you are trying it's better to just create new instance.
I test a config class, which is parsing a config file and allows me to get the various settings for an app.
My goal is to mock the parse() method of the Config class, which is called in the constructor and to set what this method is returning in the constructor.
This way, it prevents file_get_contents() from being called (in the parse() method) and enables me to have a Config class with the config property already set to contain an array of properties.
But I haven't succeeded doing that.
Here is the code:
The config class:
<?php namespace Example;
use Symfony\Component\Yaml\Parser;
class Config
{
private $parser;
private $config;
public function __construct(Parser $parser, $filePath)
{
$this->parser = $parser;
$this->config = $this->parse($filePath);
}
public function parse($filePath)
{
$fileAsString = file_get_contents($filePath);
if (false === $fileAsString) {
throw new \Exception('Cannot get config file.');
}
return $this->parser->parse($fileAsString);
}
public function get($path = null)
{
if ($path) {
$config = $this->config;
$path = explode('/', $path);
foreach ($path as $bit) {
if (isset($config[$bit])) {
$config = $config[$bit];
}
}
return $config;
}
return false;
}
}
The test:
<?php namespace Example;
class ConfigTest extends \PHPUnit_Framework_TestCase
{
private function getConfigTestMock($configAsArray)
{
$parser = $this->getMockBuilder('\Symfony\Component\Yaml\Parser')
->getMock();
$configMock = $this->getMockBuilder('Example\Config')
->setConstructorArgs([$parser, $configAsArray])
->setMethods(['parse', 'get'])
->getMock();
$configMock->expects($this->once())
->method('parse')
->willReturn($configAsArray);
return $configMock;
}
/**
* #test
*/
public function get_returns_false_if_no_path_given()
{
$configMock = $this->getConfigTestMock(['param1' => 'value1']);
// Testing further...
}
}
I suggest you to make a functional test mocking the interaction with the file system, without do partial mocking of the tested class.
I recently discover the vfsStream library used in a great article of William Durand about Symfony2 and DDD.
So you can install this library in your composer.json (I tested the solution with the 1.4 version) and try this example test class:
<?php
namespace Acme\DemoBundle\Tests;
use Acme\DemoBundle\Example\Config;
use org\bovigo\vfs\vfsStream;
use Symfony\Component\Yaml\Parser;
class ConfigTest extends \PHPUnit_Framework_TestCase
{
/**
* #test
*/
public function valid_content()
{
$content = "param1: value1";
$root = vfsStream::setup();
$file = vfsStream::newFile('example.txt')
->withContent($content)
->at($root);
$filepath = $file->url();
$parser = new Parser();
$config = new Config($parser, $filepath);
$this->assertEquals("value1", $config->get("param1"));
}
}
Hope this help
For test the Config class you need to mock only the Parser and use the real Config class. As Example:
<?php
namespace Acme\DemoBundle\Tests;
use Acme\DemoBundle\Example\Config;
class ConfigTest extends \PHPUnit_Framework_TestCase
{
private function getConfigTestMock($configAsArray)
{
$parser = $this->getMockBuilder('\Symfony\Component\Yaml\Parser')
->getMock();
$parser->expects($this->once())
->method('parse')
->willReturn($configAsArray);
$configMock = new Config($parser,"fakePath");
return $configMock;
}
/**
* #test
*/
public function get_returns_false_if_no_path_given()
{
$configMock = $this->getConfigTestMock(['param1' => 'value1']);
$this->assertEquals("value1",$configMock->get("param1"));
// Testing further...
}
}
Hope this help