PHP Import Foreign Class' Method into MyClass - php

Wondering if this is possible in PHP Land:
Let's say I have a class as follows:
class myClass{
var $myVar;
...
myMethod(){
$this->myVar = 10;
}
}
and another class:
class anotherClass {
...
addFive(){
$this->myVar += 5;
}
}
The 'anotherClass' is 3500 lines long and I just want the single 'addFive' method to use in myClass.
Is there a way I can import the function and be able to call it in my class and the $this would reference the myClass object?
Is this good/bad practice?
(optional) How does this work in Python? (Just curious as I'm starting to learn Python)

The easiest way to do this is have one class extend the other
class myClass extends anotherClass {
}
The myClass class now has access to all the methods of anotherClass that are public or protected.
If you only want the class to have one method of the other, or it's not practical to have one class extends from the other, there's nothing built into PHP that will allow you to do this. The concept you're looking to Google for is "Mixin", as in Mix In one class's functionality with another. There's an article or two on some patterns you could try to achieve this functionality in PHP, but I've never tried it myself.
Good idea/Bad Idea? Once you have the technique down it's convenient and useful, but costs you in performance and makes it harder for a newcomer to grok what you're doing with your code, especially (but not limited to) someone less familiar with OO concepts.

A better approach would be to move the complex method into its own class. Then both of your classes can instantiate it, pass any necessary data, and call the method.

If your myClass extends anotherClass it inherits all the methods and properties of anotherClass (except those marked private).
class AnotherClass {
protected $myVar;
public function addFive(){
$this->myVar += 5;
}
}
class MyClass extends AnotherClass {
public function __construct() {
$this->myVar = 0;
}
public function myMethod(){
$this->myVar = 10;
}
}
$m = new MyClass;
$m->myMethod();
$m->addFive();
var_dump($m);
prints
object(MyClass)#1 (1) {
["myVar":protected]=>
int(15)
}

Related

PHP: How can I call child methods from the base class?

From my understanding, it is good practice to not give a class too many responsibilities and good to split into sub classes, I am new to programming, so my idea was to do the following:
<?php
class ChildClass extends ParentClass
{
public static function child()
{
echo "Child";
}
}
class ParentClass
{
public static function parentF()
{
echo "Parent";
}
}
ParentClass::child();
However, that fails because the Parent does not have access to the child function. From what I am describing, what should I be doing instead? My goal is to learn how to split a big class into multiple to make things easier to maintain.
Classes can only access their parent like you concluded, not the other way around. Extending make the parent functions available in the child.
So what is possible is:
ChildClass::parentF();

PHP defining private abstract function/method

Went over a thing like this and I don't know
abstract class Foo {
abstract private function test();
}
Is this a nonsense or NOT?
If not please explain why.
if you speak about private range inside you abstract class, no it is not a nonsence
Since an abstract class can contain functionality (as opposed to an interface) it can have private variables or methods.
I will give you this link with a great answer (even it is in java, it is the same with php) Why is there a private access modifier in an abstract class in Java, even though we cannot create an instance of an abstract class?
Abstract methods cannot be private, because by definition they must be implemented by a derived class. If you don't want it to be public, it needs to be protected, which means that it can be seen by derived classes, but nobody else.
The PHP manual on abstract classes shows you examples of using protected in this way.
http://php.net/manual/en/language.oop5.abstract.php
It makes sense if you want to make that method inaccessible further down in the inheritance chain, e.g. grandchildren of that abstract class. For example:
abstract class Foo {
abstract private function test();
}
class FooChild extends Foo {
private function test()
{
// Here you implement the body of the method
}
public function bar()
{
$this->test(); // This will work
// Do something else
}
}
class FooGrandChild extends FooChild {
}
$grandchild = new FooGrandChild();
$grandchild->test(); // This will throw an exception

Can I use provided approach to access PHP variables in OOP?

Here's some code to clarify the question.
Application.php:
class Application {
var $class1;
var $class2;
function __construct() {
include_once('Class1.php');
include_once('Class2.php');
$this->class1 = new Class1($this);
echo $this->class1->testvar; // echoes 1
$this->class2 = new Class2($this);
echo $this->class1->testvar; // echoes 2
}
}
Class1.php:
class Class1 {
var $app;
var $testvar = 1;
function __construct($app) {
$this->app = $app;
}
}
Class2.php:
class Class2 {
var $app;
function __construct($app) {
$this->app = $app;
$this->app->class1->testvar = 2;
}
}
What's wrong with this approach?
I noticed in some cases a recursion occurs and the consistency is not hmmm "consistent"...
Any help on the issue is appreciated.
Mainly I need to be able to access Class1 variables from Class2, extends didn't work well for these purposes.
This:
$this->app->class1->testvar = 2;
is breaking the Law of Demeter:
The Law of Demeter (LoD) or principle of least knowledge is a design
guideline for developing software, particularly object-oriented
programs. In its general form, the LoD is a specific case of loose
coupling. The guideline was proposed at Northeastern University
towards the end of 1987, and can be succinctly summarized in one of
the following ways:
Each unit should have only limited knowledge about other units: only
units "closely" related to the current unit.
Each unit should only talk to its friends; don't talk to strangers.
Only talk to your immediate friends.
The fundamental notion is that a given object
should assume as little as possible about the structure or properties
of anything else (including its subcomponents), in accordance with the
principle of "information hiding".
Your Class2 is making a lot of assumptions about what Application looks like, making the design of Application inflexible because Class2 depends on it. You should only inject the immediately required dependencies into a class to preserve flexibility. Class2 would look a lot better like this:
class Class2 {
protected $class1;
public function __construct(Class1 $class1) {
$this->class1 = $class1;
$this->class1->setTestVar(2);
}
}
Make properties protected to encapsulate them.
If you require Class1, type hint for Class1 and require Class1, not some intermediate object which you don't really need.
Use setter methods like setTestVar instead of setting public properties. Again: encapsulation. You also preserve the flexibility to change your internal implementation of Class1 around, as long as the method setTestVar stays as it is. Think about using a defined interface between objects, not just mess around with other object's properties.
just extend the class1 to access it's method and variable, and since class1 extends the class class2 you will also be able to access the method and variable it contains
You can try this,
application.php
include_once('class1.php');
include_once('class2.php');
class application extends class1{
function hello(){
// variable from class1
echo $this->class1var."<BR>";
// variable from class2
echo $this->class2var."<BR>";
}
}
class1.php
class class1 extends class2{
public $class1var = 'hello';
}
class2.php
class class2 {
public $class2var = 'world';
}
calling the method hello
$app = new application();
$app->hello();
result:
hello
world

Alternative model for PHP abstract static class methods

Ok, so I've read lots of posts on here about this, but I think this is a specific and new question.
I want the functionality of what lots of us on here wrongly call an "abstract static method". That is: I want a class that insists classes that extend it implement certain static methods.
It seems there are two roads round the much discussed problem of not allowing abstract static, but both seem inelegant.
Problem
The following generates an error: "PHP Strict Standards: Static function A::fn() should not be abstract".
<?php
abstract class A
{
abstract static public function fn();
}
class B extends A
{
static public function fn()
{
// does something on class vars etc.
}
}
Solution 1: use Interfaces
<?php
interface iA {
static function fn();
}
abstract class A implements iA
{
} // obviously this would have other stuff in it in reality
class B extends A
{
static public function fn()
{
// does something on class vars etc.
}
}
The problem with this is that an interface assumes (dictates) that all the methods be public. So while this achieves the goal of insisting that sub-classes of an abstract class have certain static methods, it can only be used for public methods; there is still no way to ensure subclasses of A implement a protected static method.
Protected static methods are useful when the method works entirely on static data but ought not to be called from 'outside'.
Solution 2: exceptions
abstract class A
{
static public function fn()
{
throw new Exception(get_called_class() . " must implement fn()");
}
}
class B extends A
{
static public function fn()
{
// does something on class vars etc.
}
}
This works at runtime if fn() when called. But it's not useful to have to deal with coding syntax mistakes at runtime. And while this could be a hack for one method, it's a lot more code for each method.
Is there something so wrong with this design that the language rightly forbids it? Seems odd that there are various ways to insist subclasses provide most types of method, but not static ones.
It's because static methods belong to the class where they are defined. A::fn() and B::fn() are two different methods, regardless of the inheritance tree. So it makes little sense to define A::fn() as abstract.
Maybe your methods in question should not be abstract at all? If you want to use any kind of polymorphism, there should be objects involved.
I might be totally wrong, but I have no problem in using
abstract class A
{
abstract static public function fn();
}
class B extends A
{
static public function fn()
{
print 1;
}
}
B::fn();
It produces 1 as an output. I have run your code in here. What version of php do u use ?

Can you code a class function outside of a class in PHP?

In C++, I code this way:
//foo.h
class cBar
{
void foobar();
}
//foo.cpp
void cBar::foobar()
{
//Code
}
I tried to do this on PHP but the parser would complain. PHP's documentation also doesn't help. Can this be done in PHP?
No. You need to including all your function definitions inside the class block. If defining your functions in a separate structure makes you feel better you could use an interface.
interface iBar
{
function foobar();
}
class cBar implements iBar
{
function foobar()
{
//Code
}
}
I'd suggest just getting used to coding in a new way. It's easy to code consistantly within a single language, but I think you are fighting a loosing battle if you want to do the same across languages.
You can't really do this in the same manner.
You can use class abstraction and interfaces, though. The main difference between the two is that and interface does not allow you to specify the function body, where (not abstract) methods in an abstract object can hold all kinds of default behaviour.
Abstraction:
abstract class cBar
{
// MUST be extended
abstract protected function foobar();
// MAY be extended
protected function someMethod()
{
// do stuff
}
}
class cBarExtender extends cBar
{
protected function foobar()
{
// do stuff
}
}
Interfacing:
interface cBar
{
// MUST be implemented
protected function foobar();
}
class cBarImplementation implements cBar
{
protected function foobar()
{
// do stuff
}
}
The language doesn't really provide this feature but if you really want it, you can install the ClassKit extension which will let you do some dynamic class modifications at run-time.

Categories