PHP OOP pass variables to sub classes - php

I am setting up variable values in a constructor function. To keep everything organised, I have created other classes which will only be instantiated once in the "application" class.
I want to pass protected variables value to other classes(frotend, backend ...). I know we can create same variables in these classes & pass variables as arguments. This will lead to a lot of code repetition.Is there any better way around?
Thanks
class application{
protected $name;
protected $version;
protected $slug;
public function __construct(){
$this->name = $name;
$this->version = $version;
$this->slug = $slug;
$this->includes();
}
public function create_settings(){
//Only one instantiation
$frontend = new Frontend_Settings();
$backend = new Backend_Settings;
//.. more like these
}
}
class Frontend_Settings{
public function __construct(){
print_r($name.$version.$slug);
}
}
class Backend_Settings{
public function __construct(){
print_r($name.$version.$slug);
}
}
$firstapp = new application( 'First app', '1.0', 'first-app');
$secondapp = new application( 'Second app', '1.0', 'second-app');

Off the top of my head...
<?php
class application{
protected $name;
protected $version;
protected $slug;
public function __construct(){
$this->name = $name;
$this->version = $version;
$this->slug = $slug;
// you might want traits instead?
$this->includes();
}
public function create_settings(){
//Only one instantiation
$frontend = new Frontend_Settings($this);
$backend = new Backend_Settings($this);
//.. more like these
}
public function name($name=null) {
if($name) {
$this->name = $name;
}
return $this->name;
}
public function version($version = null) {
if($version) {
$this->version = $version;
}
return $this->version;
}
public function slug($slug = null) {
if($slug) {
$this->slug = $slug;
}
return $this->slug;
}
}
class Frontend_Settings{
public function __construct($app){
$this->app = $app;
printf(
"%s.%s.%s",
$app->name(),
$app->version(),
$app->slug()
);
}
}
class Backend_Settings{
public function __construct($app){
$this->app = $app;
printf(
"%s.%s.%s",
$app->name(),
$app->version(),
$app->slug()
);
}
}
$firstapp = new application( 'First app', '1.0', 'first-app');
$secondapp = new application( 'Second app', '1.0', 'second-app');
Be aware, though, that if Frontend or Backend makes any changes to $app, that change will be passed by reference: i.e., if you change it in front end, it's changed in back end.

Related

Method Chaining in CodeIgniter Library

I've been working on a script for work. It's to use Slack with PHP. At work we use CodeIgniter (sad face) so I have to accommodate and I decided to write my script as a Library.
There isn't an issue here in that the code doesn't work, as it works fine, but I am just interested to know how I can apply method chaining when calling the library so myself and my colleagues can code cleaner when we use the library.
Here's the Library I wrote - I'm more of a programmer in-training so my OOP knowledge is limited.
<?php defined('BASEPATH') OR exit('No direct script access allowed');
include('../vendor/autoload.php');
use GuzzleHttp\Client;
class Slack {
protected $ci;
private $channel;
private $endpoint;
private $icon;
private $username;
public function __construct()
{
$this->ci =& get_instance();
$this->ci->config->load('slack');
$this->baseUri = $this->ci->config->item('base_uri');
$this->channel = $this->ci->config->item('channel');
$this->endpoint = $this->ci->config->item('endpoint');
$this->icon = $this->ci->config->item('icon');
$this->username = $this->ci->config->item('username');
$this->client = new Client([
'base_uri' => $this->baseUri
]);
}
public function getChannel()
{
return $this->channel;
}
public function setChannel($channel)
{
$this->channel = $channel;
return $this;
}
public function getEndpoint()
{
return $this->endpoint;
}
public function setEndpoint($endpoint)
{
$this->endpoint = $endpoint;
return $this;
}
public function getIcon()
{
return $this->icon;
}
public function setIcon($icon)
{
(mb_substr($icon, 0, 1) == ':')
? $this->iconType = 'icon_emoji'
: $this->iconType = 'icon_url';
$this->icon = $icon;
return $this;
}
public function getIconType()
{
return ($this->iconType) ? $this->iconType : 'icon_emoji';
}
public function getUsername()
{
return $this->username;
}
public function setUsername($username)
{
$this->username = $username;
return $this;
}
public function to($channel)
{
$this->setChannel($channel);
return $channel;
}
public function from($username)
{
$this->setUsername($username);
return $username;
}
public function icon($icon)
{
$this->setIcon($icon);
return $icon;
}
public function payload($text)
{
$payload = [
'channel' => $this->getChannel(),
$this->getIconType() => $this->getIcon(),
'link_names' => 1,
'text' => $text,
'username' => $this->getUsername(),
];
return $payload;
}
public function send($text)
{
$payload = json_encode($this->payload($text));
$this->client->post($this->getEndpoint(), [
'body' => $payload
]);
return $this;
}
}
Now I'm using this in our API, which is coded in a Controller, and this is how I am calling the methods:
<?php
// ...
$this->load->library('slack');
$this->slack->icon(':hotdog:');
$this->slack->send('Hello...');
As I said, this works fine...
I wanted though, to be able to do method chaining, like so:
<?php
// ...
$this->slack->icon(':hotdog:')->send('Hello...');
Can you tell me if this is possible and how to achieve it?
Thank you.
As i can see to archive what you want you just need to change that
public function icon($icon)
{
$this->setIcon($icon);
return $icon;
}
to that
public function icon($icon)
{
$this->setIcon($icon);
return $this;
}
and then you will be able to do what you want
$this->slack->icon(':hotdog:')->send('Hello...');
Anyway your icon method no need to return $icon you already have getIcon method
also your send method calling payload method before make request so that should work

Using static methods and static property as `global`

Is there anything wrong with this practice example?
class Test {
static $_instance = null; // self
protected $_name = null;
/**
* Get instance
* #return [type] [description]
*/
public static function getInstance() {
if(is_null(self::$_instance))
self::$_instance = new self;
return self::$_instance;
}
/**
* Set name
*/
public static function setName($name) {
self::getInstance()->_name = $name;
}
public static function getName() {
return self::getInstance()->_name;
}
}
And then doing this anywhere:
Test::setName('Some name');
Test::getName(); // returns "Some name"
Instead of:
// somewhere early
$test = new Test;
// somewhere else
function someRandomFunction() {
global $test;
$test->setName('Hello there');
}
// somewhere else
function AnotherRandomFunction() {
global $test;
return $test->getName();
}
I wrote a test that looks like this:
class TestTest extends WP_UnitTestCase {
function testInstance() {
$someName = 'Hello ' . time();
Test::setName($someName);
$this->assertEquals(Test::getName(), $someName);
}
}
This being my very first test I write, I am unsure whether my test and approach to this is considered good practice.

PHP simple chain class methods without create object

in this below class i want to use class like with static methods and for use class methods without create new object from parent.
for example:
<?php
class Permission
{
protected $permission = false;
protected $id = 0;
public static function __construct()
{
return new static;
}
public function user( $id )
{
$this->id = $id;
}
public function check()
{
$this->permission = true;
}
public function item( $item )
{
return $item;
}
}
$bar = Permission::user(100)->item("HELLO");
print_r($bar);
this code not working and have problem. how to resolve this class problem?
That will not work because user method is not static, try changing this two methods, and this is good way of generating objects
public function __construct($id)
{
$this->id = $id;
}
public static function user( $id )
{
return new static($id);
}
I'd suggest you a singleton pattern, like this
class Permission
{
static protected $permission = false;
static protected $id = 0;
private static $_instance = null;
private function __construct () { }
public static function getInstance()
{
if (self::$_instance === null) {
self::$_instance = new self;
}
return self::$_instance;
}
public static function user( $userId )
{
self::$id = $userId;
return self::$_instance;
}
public static function check()
{
self::$permission = true;
return self::$_instance;
}
public static function item( $item )
{
return $item;
}
}
$bar = Permission::getInstance()->user(100)->item("HELLO");
print_r($bar);
You can chain methods in 'dynamic' classes by returning $this at the end of method (remember, you have a static).
class A {
public function someMethod()
{
// some code
return $this
}
public function otherMethod()
{
// some code
return $this
}
$a = new A();
$a->someMethod()->otherMethod();
}

PHP multiple-inheritance

I try to inherit multiple classes from each other, but something wrong happens somewhere. The classes are the following:
Part of the MobilInterface class:
class MobileInterface
{
private $config;
private $errorData;
private $data;
private $output;
private $job;
public $dbLink;
public function __construct($config) {
$this->config = $config;
}
public function initialize($job) {
$this->dbLink = $this->createDbInstance($this->config);
require_once 'jobs/' . strtolower($this->config->joblist[$job]) .'.php';
$this->job = new $this->config->joblist[$job]($this);
}
public function run($params) {
$job = $this->job;
$this->data = $this->job->run($_GET);
}
}
Mobil Interface is the main interface, which calls the Kupon class based on a string in the $config. My problem is that i want more Kupon like classes and wanted to make a BaseJob class to be able to write each Job class without the constructor.
The problem is that the Kupon class can't see the $dbLink and the $config variables.
The BaseJob class:
<?php
class BaseJob
{
public $interface;
public $dbLink;
public $config;
public function __construct(MobileInterface $interface) {
$this->interface = $interface;
$this->config = $this->interface->get('config');
$this->dbLink = $this->interface->get('dbLink');
}
}
?>
And the Kupon class:
function __construct(){
parent::__construct(MobileInterface $interface);
}
}
?>

Using $this when not in object context. wordpress plugin

I am building a wordpress plugin in some MVC style and i have setup almost every thing but when using call_user_func to call the request action class, I am not able to use the $this with the requested class.
Here is my code so far...
class Action{
protected $class;
protected $method;
protected $args = array();
protected $template='settings/index';
public function __construct() {
$this->getRequest();
}
public function getRequest(){
if(isset($_GET['c'])){
$route = $_GET['c'];
$parts = explode('/',$route);
if(isset($parts[0]))
$this->class = $parts[0];
if(isset($parts[1]))
$this->method = $parts[1];
if(isset($parts[2]))
$this->args[] = $parts[2];
if(isset($parts[3]))
$this->args[] = $parts[3];
}
}
public function render(){
extract($this->data);
ob_start();
require(LINKWAG_VIEW .DS. $this->template . P);
$this->output = ob_get_contents();
ob_end_clean();
return $this;
}
public function output(){
echo $this->output;
}
}
class Grv extends Action{
public function __construct() {
parent::__construct();
add_action('admin_menu', array($this,'setup'));
}
public function setup(){
add_menu_page( 'LinkWag', 'LinkWag', 'manage_options', 'linkwag',array($this,'execute'), plugins_url( 'myplugin/images/icon.png' ), 6 );
}
public function execute(){
if($this->class){
$this->controller = call_user_func_array(array($this->class,$this->method), $this->args);
}
}
}
The requested class goes here
class Settings extends Grv{
public function __construct() {
//parent::__construct();
}
public function view($id=false){
$this->template = 'settings/view'; // using $this here craetes a fatal error
$this->render();
}
}
suppose i requested
admin.php?page=grv&c=settings/view/2
please tell me what i am doing wrong..
use $this->render() instead of $this->class->render();
another is: add ucfirst because your class name is in first letter capital and you are passing small case in arguments.
$this->controller = call_user_func_array(array(ucfirst($this->class), $this->method), $this->args)

Categories