I have declared the beats function and am trying to use it. What is the difference between var_dump(is_a($sci, 'Scissors')) and var_dump($roc->beats($sci))? When I run this code the first var_dump returns true and the second false. I want both to return true.
abstract Class Option
{
private $beats;
public function beats($opponentsChoice)
{
return is_a($opponentsChoice, $this->beats);
}
}
Class Rock extends Option
{
private $beats = 'Scissors';
}
Class Paper extends Option
{
private $beats = 'Rock';
}
Class Scissors extends Option
{
private $beats = 'Paper';
}
$roc = new Rock;
$pap = new Paper;
$sci = new Scissors;
var_dump(is_a($sci, 'Scissors'));
var_dump($roc->beats($sci));
The problem is your private variables.
private variables are scoped only to the class they are defined in. Option::$beats is a different variable than Rock::$beats.
If you change your variables to be protected instead, that will work, since all members of a class hierarchy will share protected variables (and methods).
Related
I don't understand what is the different between private method and protected method in Object Oriented PHP. After make a method private , I'm able to access it from extends class. Please check the code below -
<?php
class person{
private function namedilam(){
return "likhlam";
}
public function kicu(){
return $this->namedilam();
}
}
class second extends person{
}
$info = new second;
echo $info->kicu();
The difference will become clear when you do it like this:
class Liam {
private getFirstName() {
return "Liam";
}
public function getName() {
return $this->getFirstName();
}
}
class Max extends Liam {
private function getFirstName() {
return "Max";
}
}
class Peter extends Liam {
public function getLiamsName() {
return $this->getFirstName();
}
}
$max = new Max();
echo $max->getName();
// returns "Liam", not "Max" as you might expect
$peter = new Peter();
echo $peter->getLiamsName();
// PHP Fatal error: Uncaught Error: Call to private method Liam::getFirstName() [...]
Max will return "Liam" because the getName() calls getFirstName() in the Liam class, not the one from the class extending it. This means with private methods you can make sure that whenever in your class you call this method exactly this one is used and it will never be overwritten.
To explain it in general terms:
private methods are only accessible inside the class. They can not be overwritten or accessed from outside or even classes extending it.
protected methods are accessible inside the class and in extending classes, but you can't call them from outside like:
$max = new Max();
$max->iAmProtected();
This will neither work with private or protected methods.
I am working with a plugin where there is a protected function like so
<?php
class CustomUploadHandler extends UploadHandler {
protected function get_user_id() {
//If I manually enter a value here, the value passes along
return ('myvariable');
}
}
?>
Yet when I make a variable like
<?php $myvar = 'myvariable'; ?>
and try to insert it into the function like this
<?php
class CustomUploadHandler extends UploadHandler {
protected function get_user_id() {
//If I use a variable, the value is lost
return ($myvar);
}
}
?>
it completely fails...
I am unfamiliar with protected classes and also how return() works so any help would be greatly appreciated.
I have tried many lines of code such as
print $myvar; return $myvar; echo $myvar; with and without ()
Don't introduce global state via the global keyword. You'll be welcoming a world of pain down the line.
Instead, inject the dependency (the value, a user ID in this case) into the class when it's created, or with a setter.
class CustomUploadHandler extends UploadHandler
{
private $user_id;
protected function get_user_id()
{
return $this->user_id;
}
// setter injection; the value is
// passed via the method when called
// at any time
public function set_user_id($user_id)
{
$this->user_id = $user_id;
}
// constructor injection; the value is
// passed via the constructor when a new
// instance is created
public function __construct($user_id)
{
$this->set_user_id($user_id);
}
}
Then when you have an instance of this class:
// creates and sets $user_id = 42
$customUploadHandler = new CustomUploadHandler(42);
// sets $user_id = 77
$customUploadHandler->set_user_id(77);
Protected means that only the class itself, the parent class and the childs of the class where the function is defined can use the function. So it depends from where you call the function for it to work. return statements without brackets should be fine.
I'm new to the extends classes and am having a little trouble with is issue.
I'm trying to get a variable initiated by use of a different function then the construct.
It should make more sense if you look below.
class A
{
private static $_var;
function __construct($EGGS)
{
$this->_var=$EGGS
}
private static function _ini()
{
$this->_var="hard coded value";
}
}
class B extends A
{
//How do I initiate private static $_var with the _ini() instead of using
//the __construct here in good old class B?
}
$a = new A("foo");//works just fine
$b = new B;
I have a protected function that is defined within a certain class. I want to be able to call this protected function outside of the class within another function. Is this possible and if so how may I achieve it
class cExample{
protected function funExample(){
//functional code goes here
return $someVar
}//end of function
}//end of class
function outsideFunction(){
//Calls funExample();
}
Technically, it is possible to invoke private and protected methods using the reflection API. However, 99% of the time doing so is a really bad idea. If you can modify the class, then the correct solution is probably to just make the method public. After all, if you need to access it outside the class, that defeats the point of marking it protected.
Here's a quick reflection example, in case this is one of the very few situations where it's really necessary:
<?php
class foo {
protected function bar($param){
echo $param;
}
}
$r = new ReflectionMethod('foo', 'bar');
$r->setAccessible(true);
$r->invoke(new foo(), "Hello World");
That's the point of OOP - encapsulation:
Private
Only can be used inside the class. Not inherited by child classes.
Protected
Only can be used inside the class and child classes. Inherited by child classes.
Public
Can be used anywhere. Inherited by child classes.
If you still want to trigger that function outside, you can declare a public method that triggers your protected method:
protected function b(){
}
public function a(){
$this->b() ;
//etc
}
If the parent's method is protected, you can use an anonymous class:
class Foo {
protected function do_foo() {
return 'Foo!';
}
}
$bar = new class extends Foo {
public function do_foo() {
return parent::do_foo();
}
}
$bar->do_foo(); // "Foo!"
https://www.php.net/manual/en/language.oop5.anonymous.php
You can override this class with another where you make this public.
class cExample2 extends cExample {
public function funExample(){
return parent::funExample()
}
}
(note this won't work with private members)
But the idea of private and protected members is to NOT BE called from outside.
Another option (PHP 7.4)
<?php
class cExample {
protected function funExample(){
return 'it works!';
}
}
$example = new cExample();
$result = Closure::bind(
fn ($class) => $class->funExample(), null, get_class($example)
)($example);
echo $result; // it works!
If you want to share code between your classes you can use traits, but it depends how you want use your function/method.
Anyway
trait cTrait{
public function myFunction() {
$this->funExample();
}
}
class cExample{
use cTrait;
protected function funExample() {
//functional code goes here
return $someVar
}//end of function
}//end of class
$object = new cExample();
$object->myFunction();
This will work, but keep in mind that you don't know what your class is made of this way. If you change the trait then all of your classes which use it will be altered as well. It's also good practice to write an interface for every trait you use.
here i can give you one example like below
<?php
class dog {
public $Name;
private function getName() {
return $this->Name;
}
}
class poodle extends dog {
public function bark() {
print "'Woof', says " . $this->getName();
}
}
$poppy = new poodle;
$poppy->Name = "Poppy";
$poppy->bark();
?>
or one another way to use with latest php
In PHP you can do this using Reflections. To invoke protected or private methods use the setAccessible() method http://php.net/reflectionmethod.setaccessible (just set it to TRUE)
I am using Laravel. i was facing issue while access protected method outside of class.
$bookingPriceDetails = new class extends BookingController {
public function quotesPrice( $req , $selectedFranchise) {
return parent::quotesPrice($req , $selectedFranchise);
}
};
return $bookingPriceDetails->quotesPrice($request , selectedFranchisees());
here BookingController is Class name from which i want to get protected method. quotesPrice( $req , $selectedFranchise) is method that i want to access in different Class.
I have been searching for a while but I could not find the answer, what are the differences between these two ways of inicialize a variable class in PHP?:(if there are)
class MyClass
{
private $myVariable='something';
public function __construct()
{
}
}
class MyClass
{
private $myVariable;
public function __construct()
{
$this->myVariable='something';
}
}
If you want to initialize the variable with a default value inside the class, choose method 1.
If you want to initialize the variable with a outside value, pass the variable through the constructor and choose method 2.
See this scenario:
class Parent {
protected $property1; // Not set
protected $property2 = '2'; // Set to 2
public function __construct(){
$this->property1 = '1'; // Set to 1
}
} // class Parent;
class Child extends Parent {
public function __construct(){
// Child CHOOSES to call parent constructor
parent::__construct(); // optional call (what if skipped)
// but if he does not, ->property1 remains unset!
}
} // class Child;
This is a difference between the two calls. parent::__construct() is optional for child classes that inherit from a parent. So:
if you have scalar (as in is_scalar()) properties that need to be preset, do it in the class definition to be sure that they exist in child classes too.
if you properties that depend on arguments or are optional, put them in the constructor.
It all depends on how you design your code's functionality.
There's no right of wrong here, it's only what's right for you.
I like to do it somewhat like the second way to facilitate lazy-loading. Simple values I will set when declaring the member variable.
class WidgetCategory
{
/** #var array */
private $items;
/**
*
* #return array
*/
public function getItems()
{
if (is_null($this->items)) {
$this->items = array();
/* build item array */
}
return $this->items;
}
}
You can only use constant values if you don't choose to initialize the variable in the constructor. Here a little example:
define('MY_CONSTANT', 'value');
class MyClass
{
// these will work
private $myVariable = 'constant value';
private $constant = MY_CONSTANT;
private $array = Array('value1', 'value2');
// the following won't work
private $myOtherVariable = new stdClass();
private $number = 1 + 2;
private $static_method = self::someStaticMethod();
public function __construct($param1 = '')
{
$this->myVariable = $param1;
// in here you're not limited
$this->myOtherVariable = new stdClass();
$this->number = 1 + 2;
$this->static_method = self::someStaticMethod();
}
}
Take a look at this Manual Page to see what values are allowed to be directly assinged to properties: http://php.net/manual/en/language.oop5.properties.php
There may be more differences ...