I am new to OOP so please bear with me.
I have defined a singleton trait to store instances of all classes and it all works fine when I call the classes with className::get_instance(). However, I can't figure how to pass arguments to a class's constuctor function with Singleton?
This is my Singleton trait:
trait Singleton{
final public static function get_instance() {
static $instance = [];
$called_class = get_called_class();
if( !isset( $instance[ $called_class ] ) ) {
$instance[$called_class] = new $called_class();
}
return $instance[ $called_class ];
} }
And this is my New_Post class
class New_Post{
use Singleton;
protected function __construct( $first_name, $last_name, $email, $phone, $date ){
$this->first_name = $first_name;
$this->last_name = $last_name;
$this->email = $email;
$this->phone = $phone;
$this->date = $date;
}
}
Now I want to call this class from a different file so normally I use:
New_Post::get_instance();
But as you can see in the New_Post constructor function, I need to pass $arg1 and $arg2 to its instance. How to go about passing them. Thanks.
Change get_instance() to take arguments and pass them along when calling $called_class().
<?php
trait Singleton{
final public static function get_instance(...$args) {
static $instance = [];
$called_class = get_called_class();
if( !isset( $instance[ $called_class ] ) ) {
$instance[$called_class] = new $called_class(...$args);
}
return $instance[ $called_class ];
}
}
class New_Post{
use Singleton;
protected function __construct( $first_name, $last_name, $email, $phone, $date ){
$this->first_name = $first_name;
$this->last_name = $last_name;
$this->email = $email;
$this->phone = $phone;
$this->date = $date;
}
}
$post = New_Post::get_instance("First", "Last", "email", "123-456-7890", "today");
var_dump($post);
DEMO
Related
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.
I'm developing a WordPress plugin where I want to connect different apps. I created a class 'App' and I'm extending the 'App' class with different classes.
Now I would like to collect all the objects of those instances so I can list them out.
Anyone who can help me out? If interested I'm even willing to pay a good developer who can teach me this for future development. Looking forward to your replies.
This is my current code:
class App {
public function __construct( $id, $name, $label, $description, $subscription_id ) {
$this->id = $id;
$this->name = $name;
$this->label = $label;
$this->description = $description;
$this->subscription_id = $subscription_id;
}
}
class App_Vimeo extends App {
public function __construct( $id, $name, $label, $description, $subscription_id ) {
$this->id = $id;
$this->name = $name;
$this->label = $label;
$this->description = $description;
$this->subscription_id = $subscription_id;
}
}
class App_Facebook extends App {
public function __construct( $id, $name, $label, $description, $subscription_id ) {
$this->id = $id;
$this->name = $name;
$this->label = $label;
$this->description = $description;
$this->subscription_id = $subscription_id;
}
}
class Get_Apps {
public function __construct() {
$this->get_apps();
}
public static function get_apps() {
$apps = array();
$apps[] = new App_Vimeo( 1, 'vimeo', 'Vimeo', 'Vimeo app description', 1 );
$apps[] = new App_Facebook( 1, 'facebook', 'Facebook', 'Facebook app description', 1 );
return $apps;
}
}
$apps = Get_Apps::get_apps();
var_dump( $apps );
`
have a go with this:
$apps = Get_Apps::get_apps();
foreach($apps as $a) {
echo get_class($a) . '<HR>';
}
The get_class function returns the name of the class in which the parameter object identifies itself as.
Parent
class MWCEMod {
private static $mod;
public function get_mod(){
var_dump( self );
if ( null == self::$mod )
self::$mod = new MWCEMod();
return self::$mod;
}
private function __construct(){
var_dump('something1');
}
}
Child
class MWCEMod_child extends MWCEMod{
private function __construct(){
var_dump('something2');
}
}
add_action( 'MWCE_Load_Mods', array('MWCEMod_acf','get_mod') );
I would like to to change above code so MWCEMod_child::get_mod() would call self::$mod = new MWCEMod_child(); not self::$mod = new MWCEMod();. Is there any way for doing it?
I'm trying to learn oop PHP on Making Wordpress Plugin. Those are modules for main class and i load them this way:
class MonWayContentEditor {
private static $instance;
private $options;
public $plugin_url,
$plugin_dir;
public static function get_instance() {
if( get_current_user_id() == 2 ){
if ( self::$instance == null )
self::$instance = new MonWayContentEditor();
return self::$instance;
}
return null;
}
private function __construct(){
$this->options = array(
);
$this->plugin_url = plugins_url().'/monway-editor/';
$this->plugin_dir = plugin_dir_path( __FILE__ );
$this->load_modules();
do_action( 'MWCE_Load_Mods');
}
private function load_modules(){
include($this->plugin_dir.'/mods/MWCEMod.php');
if(class_exists('acf'))
include($this->plugin_dir.'/mods/acf.php');
}
}
add_action( 'plugins_loaded', array( 'MonWayContentEditor', 'get_instance' ) );
I dont know how to explain it better.
The main thing seems to be to create an instance of the derived class as opposed to the base class. I've altered the code to allow me to show the principle of using get_called_class() and then using this name to create the object.
class MWCEMod {
private static $mod;
public function get_mod(){
if ( null == self::$mod )
$className = get_called_class();
self::$mod = new $className();
return self::$mod;
}
private function __construct(){
var_dump('something1');
}
}
class MWCEMod_child extends MWCEMod{
public function __construct(){
var_dump('something2');
}
}
$n = new MWCEMod_child();
print_r($n->get_mod());
This code outputs...
.../Test/t1.php:21:
string(10) "something2"
.../Test/t1.php:21:
string(10) "something2"
MWCEMod_child Object
(
)
I'm quite new to OOP, so I got a little issue
I've created a class
class Lesson {
function Lesson( $title, $sample ) {
$this->title = $title;
$this->sample = $sample;
}
}
Then an object
$title = 'title';
$sample = false;
$lesson = new Lesson( $title, $sample );
An when I'm trying to access a property of the object
echo $lesson->title
I get this error message
"The script tried to execute a method or access a property of an
incomplete object..."
You need to change function Lesson to function __construct in order to pass those values on creation.
class Lesson {
function __construct( $title, $sample ) {
$this->title = $title;
$this->sample = $sample;
}
}
Otherwise, you'd have to create it like this:
$lesson = new Lesson();
$lesson->Lesson($title, $sample);
echo $lesson->title;
Your properties aren't defined. Try adding them at the top of the class declaration.
class Lesson {
public $title = '';
public $sample = '';
public function Lesson( $title, $sample ) {
$this->title = $title;
$this->sample = $sample;
}
}
The constructor syntax also depends on the verstion of php. If you are > 5.3.3 you should use __construct()
class Lesson {
public $title = '';
public $sample = '';
function __construct( $title, $sample ) {
$this->title = $title;
$this->sample = $sample;
}
}
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();
}