PHP - Achieve certain syntax with multiple classes - php

(PHP7) I have two classes but would like to access one class inside of another for example:
Syntax: Property::House()->getAddress();
class Property
{
protected $House;
function Property()
{
self::$House = new House();
}
public function House()
{
return self::$House;
}
}
class House
{
public function getAddress()
{
// code
}
}
does anyone know to accomplish this?, the syntax needs to be the same but the classes can change if needed

Firstly, your class setup is going to give you deprecation errors in PHP7. You'd be better off using the __construct() method in place of Property() if you're wanting to use non-static calls.
Secondly. Are you sure you don't want House to extend the Property class instead of being a property of the Property class?
Thirdly, assuming you're sure of what you're trying to achieve this should work...
<?php
class Property
{
static function House()
{
return new House();
}
}
class House
{
public function getAddress()
{
echo 'YAY!';
}
}
Property::House()->getAddress();

Related

Possible for instantiated sub class to access property set by parent class?

I'm new to object-oriented PHP, and still wrapping my head around classes and subclasses.
In this simple example, $this->siteName will be empty inside the instantiated class Two (called from class One's method "build").
Is there any way for an instance of class Two to inherit that property value set by the parent?
I know I could just turn class Two into a method of class One, but I like having separate files for organization.
Is there a better way to do this?
File One
class One {
protected $siteName;
function __construct() {
$this->siteName = 'Example';
}
public function build() {
$two = new Two();
return $two->build();
}
}
File Two
class Two extends One {
public function build() {
return "<h1>$this->siteName</h1>";
}
}
By the sound of it you're trying to solve the wrong problem.
My understanding of your question is that you basically want to have the code for public function build() in another file for organisation reasons.
Here's how:
class One {
private $siteName;
public function __construct() {
$this->siteName = 'Example';
}
use One_build;
}
Assuming you have the proper autoloading setup, or have included the files correctly, you can then have your separate file:
trait One_build {
public function build() {
return "<h1>".$this->siteName."</h1>";
}
}
This allows for a horizontal spreading of your source code.
Your code does work with a few tweaks. You need to concatenate your string's h1 tags with your variable, quotes can't be around the entire thing.
Other than that, just create an instance of the class and trying it out.
class One {
protected $siteName;
function __construct() {
$this->siteName = 'Example';
}
public function build() {
$two = new Two();
return $two->build();
}
}
class Two extends One {
public function build() {
return "<h1>".$this->siteName."</h1>";
}
}
$taco = new Two();
echo $taco->build();
This will return <h1>Example</h1>

Correct way of using polyporphism in php?

I'm new to object oriented php. And if there are no functions in the method testing() in the HumanClass, should i declare them as abstract?
<?php
class HumanClass
{
private $legs;
private $hands;
public function __construct($legs, $hands)
{
$this->legs = $legs;
$this->hands = $hands;
}
public function testing()
{
}
}
class StudentClass extends HumanClass
{
private $books;
public function __construct($legs, $hands, $books)
{
parent::__construct($legs, $hands);
$this->books = $books;
}
public function testing()
{
echo "StudentClass called.";
}
}
function callClass(HumanClass $c)
{
$c->testing();
}
$example = new StudentClass(4, 2, 1);
callClass($a);
?>
Is it possible to have something like this?
echo $a->testing();
instead of having another method to call testing().
Given the code that you give, it's far from clear what the testing() function is supposed to do other than just exist for you to try things. The answer to that will also determine whether the versions in the baseclass should remain there as empty function.
There are other options, too, e.g. that the derived class first invokes the baseclass (extending), or that the baseclass doesn't contain an abstract or concrete such function but only the derived one does. Which to choose is up to the informed programmer to decide.

Is it possible to cancel function override in parent class and use function from top level parent

class TopParent
{
protected function foo()
{
$this->bar();
}
private function bar()
{
echo 'Bar';
}
}
class MidParent extends TopParent
{
protected function foo()
{
$this->midMethod();
parent::foo();
}
public function midMethod()
{
echo 'Mid';
}
public function generalMethod()
{
echo 'General';
}
}
Now the question is if I have a class, that extends MidParent because I need to call
class Target extends MidParent
{
//How to override this method to return TopParent::foo(); ?
protected function foo()
{
}
}
So I need to do this:
$mid = new MidParent();
$mid->foo(); // MidBar
$taget = new Target();
$target->generalMethod(); // General
$target->foo(); // Bar
UPDATE
Top parent is ActiveRecord class, mid is my model object. I want to use model in yii ConsoleApplication. I use 'user' module in this model, and console app doesn't support this module. So I need to override method afterFind, where user module is called. So the Target class is the class that overrides some methods from model which uses some modules that console application doesn't support.
Try this (http://php.net/manual/en/language.oop5.final.php - not allow to overriding in the childrens):
final protected function foo()
{
$this->midMethod();
parent::foo();
}
in class MidParent and the class Target can't overrides this method.
Directly - you can't. This is how OOP works.
You can do it by a little redesign, e.g. in MidParent add method:
protected function parentFoo()
{
parent::foo();
}
and in Target:
public function foo()
{
$this->parentFoo();
}
But, again, this is only a workaround to solve your question and not a solution.
Actually, you can do this like this way with Reflection::getParentClass():
class Foo
{
public function test($x, $y)
{
echo(sprintf('I am test of Foo with %s, %s'.PHP_EOL, $x, $y));
}
}
class Bar extends Foo
{
public function test()
{
echo('I am test of Bar'.PHP_EOL);
parent::test();
}
}
class Baz extends Bar
{
public function test()
{
$class = new ReflectionClass(get_class($this));
return call_user_func_array(
[$class->getParentClass()->getParentClass()->getName(), 'test'],
func_get_args()
);
}
}
$obj = new Baz();
$obj->test('bee', 'feo'); //I am test of Foo with bee, feo
-but this is an architecture smell in any case. If you need something like this, that should tell you: you're doing something wrong. I don't want to recommend anyone to use this way, but since it's possible - here it is.
#AnatoliyGusarov, your question is interesting and in a sense you can achieve what you desire using yii and php advances features like Traits and Traits in Yii.
Given that it depends on what version of php you are using.However in yii you can achieve this by behaviors and check this SOQ.
In a nutshell you have to use language advanced features or YII framework features to come around this kind of issues,but that boils down to actual requirements

Can I/How to... call a protected function outside of a class in PHP

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.

PHP make class propery inheritable

i have 2 classes A and B that extends A. A has a public property and i want that on the instances of B that property can't be accessible. I try to explain better:
class A
{
public $prop;
}
class B extends A
{
...
}
$instance=new B;
$instance->prop; //This must throw an error like "Undefined property prop"
I tried with the final keyword but it's only available for methods not for properties. I tried also by setting the same property as private on B but PHP does not allow to change the access level from public to private or protected.
Maybe there's a simple solution to this problem but i can't find it so do you know a way to do this?
Simply change public $prop; to private $prop; by making $prop public you are making it accessible by every possible way, but making it private will make it accessible within a class only
Use magic methods
class A {
protected $_prop;
public function __get($key) {
if ($key=='prop') {
return $this->_prop;
}
}
public function __set($key, $value) {
if ($key=='prop') {
return $this->_prop = $value;
}
}
}
class B extends A {
public function __get($key) {
}
public function __set($key, $value) {
}
// how you can use it
public function foo() {
echo $this->_prop;
}
}
Hmm. Tricky!
The only idea that comes to mind is making $prop private from the start, and using magic getter and setter functions to control access. You'd have to store the access information in a separate array and then either return the correct value, or throw a fatal error in the getter function.

Categories