PHP get class initial properties from instance without reflection - php

I'll try to explain what the problem is with code
class A {
protected $a;
}
class B extends A {
protected $b;
}
$b = new B();
$b->c = true;
get_class_properties($b);
I need this function to return me only the properties which the class was declared with, excluding inherited and dynamically created properties. Expected result of the code is
Array (
[0] => string(1) 'b'
)
Is this possible without the use of reflection classes?

I came up with a solution, of course after I posted the question. I'll just add the answer in case anybody is looking for this in future.
Also if anyone has a better solution, please post!
What I came up with is I needed to add an additional method for getting the property names
public function getOwnProperties(){
return get_class_vars(__CLASS__);
}
So in the example from the question it would look like
class A {
protected $a;
public final function getOwnProperties(){
return get_class_vars(get_called_class());
}
}
class B extends A {
protected $b;
}
$b = new B();
$b->c = true;
print_r($b->getOwnProperties());
IMPORTANT
This solution does not satisfy one of the requirements from the question - it gives inherited properties as well.

Related

Aggregating Objects , need help/explanation

I have wrote this code by looking at similar code from a PHP cookbook. I have few troubles with executing and understanding it + it is not working well. Hope someone can help me.
<?php
class example {
//protected $a;
//protected $c;
public function NumberInput($number){
$this->a = $number;
}
public function NumberOutput(){
return $this->a;
}
}
class example2 {
public function __construct(){
$this->mergingclass = new example;
}
public function numberInput2($number){
$this->c = $number;
}
public function NumberOutput2(){
return $this->c;
}
public function __call($method,$arguments){
echo "called methos is $method <br> ";
;
return $this->x = $arguments;
}
}
$b = new example2;
$b->NumberInput(7);
echo $b->NumberOutput();
?>
so my questions are:
Why do I even need __construct function ? Code is working excatly the same with or without it. Or atleast I can't spot the difference with my newbie abilities. If I understand correctly it should agreggate objects but when I put it in comments nothing changes.
When I execute this code insted of number 7 I get "Array". I suppose number 7 is inside of that array, so how can I echo it ?
Thanks in advance.
First of all, __construct is like a magic method in PHP, that makes it possible to create an object out of class. Each time you write something like this:$myObject = new Object(); constructor of Object class is called by default and it creates object referenced by $myObject variable. So without that method in it, you will not be able to properly use classes and create objects.
use print_r($array) or var_dump($array) to see array structure

PHP - Two classes, talk to each other correctly

I have a small problem. I've tried searching, but I can't get the search terms quite right and was hoping someone could help.
I have an include on every page in my system that works something like this:
<?PHP
require_once("class.system.php");
require_once("class.mysql.php");
$oMySQL = new MySQL();
$oSystem = new SystemClass();
... ?>
But I have a problem. As you may guess - the MySQL class is a bunch of functions that I use to make MySQL calls easier. This isn't the only example of where I want to use it but it's a good example.
I have functions in the system class I want to be able to reference the MySQL class (And vice versa...).
As an example, I have a function in the system class that will populate a session variable with data from MySQL. The only way I can think of doing this (Which I know is wrong...) is:
class SystemClass {
function PopulateSession(){
global $oMySQL;
if($oMySQL->Select('abc')){
$_SESSION['def']= blahblahblah;
return true;
} else {
return false;
}
}
}
It works, but it means every function I want to use it, I have to use global, which I'm sure is very bad practice. Could someone advise??
Thanks
What you encountered is called composition. A good solution would be to use a dependency injection framework. An easy solution is to roll with constructor parameters.
public class A {
private $b;
public function __construct($b) {
$this->b = $b;
}
}
$b = new B;
$a = new A($b);
Or, as a more flexible solution, when you have mutual dependencies:
public class A {
private $b;
public function setB($b) {
$this->b = $b;
}
}
public class B {
private $a;
public function setA($a) {
$this->a = $a;
}
}
$a = new A;
$b = new B;
$a->setB($b);
$b->setA($a);
But the downside is that as the number of dependencies grows, it's hard to manage and remember to set all the dependencies. This is exactly the reason why Dependency Injection frameworks are popular.

Create a function inside a function into a class?

I'm trying to create some classes and i would like to use this syntax:
$my = new My();
$my->field()->test('test');
I know how to do a $my->test('test'), it's easy - but I don't know how to add a field() attribute to make an easier comprehension of my class in my code.
I can guess it's something like a class into another class - extends - but i'm not sure about that so if you know how to do something similar.
I precise it's only for a better comprehension into my class. I mean the aim is to categorize functions in this My class.
Thank you :)
If you break your php down a bit, you will understand what is going on. For example lets make this:
$my->field()->test('test');
into this (for clarification).
$newObject = $my->field();
$newObject->test('test');
From here you can observe that the return of the method $my->field() is actually an object with another method test which you can then call. It is called method chaining and can be useful at times.
Here is a test case:
class a{
public function My(){
return new b;
}
}
class b{
public function foo(){
echo 'hello bar';
}
}
$a = new a();
$a->My()->foo();
In order to carry out an action on a method the method needs to return an object.
class a {
public function b($c){
echo $c;
return $this;
}
}
would allow
$d = new a();
$d->b("foo")->b("bar");
$d->b("foo")->b("bar")->b("far")->b("tar");

PHP Classes: parent/child communication

I'm having some trouble extending Classes in PHP.
Have been Googling for a while.
$a = new A();
$a->one();
$a->two();
// something like this, or...
class A {
public $test1;
public function one() {
echo "this is A-one";
$this->two();
$parent->two();
$parent->B->two();
// ...how do i do something like this (prepare it for using in instance $a)?
}
}
class B extends A {
public $test2;
public function two($test) {
echo "this is B-two";
}
}
I'm ok at procedural PHP.
Your examples are fine, but you are showing a little confusion here:
public function one() {
echo "this is A-one";
$this->two();
$parent->two();
$parent->B->two();
}
what you want is this I think:
class A
{
function one()
{
echo "A is running one\n";
$this->two();
}
function two()
{
echo "A is running two\n";
}
}
class B extends A
{
function two()
{
echo "B is running two\n";
}
}
Then you want to make an object of type B and call function "one"
$myB = new B();
$b->one();
This will output
A is running one
B is running two
This is an example of polymorphic class behavior. The superclass will know to call the current instance's version of the function "two". This is a standard feature of PHP and most object oriented languages.
Note, that a superclass never knows about subclasses, the only reason you can call the "two" method and have B's version run is because the function "two" was defined in the parent (A) class.
It can't be done. First off, class A is class B's parent, so using something with parent is right off the list.
There is a number of things that goes for a child class that does not go for a parent class:
Class B needs A to be present in order to work
Class B can do everything A can plus more
Class B has access (as far as it is allowed to access) all data of class A
None of these things is true in reverse, so together they make up the reason why you cannot call a child's function.
Have a close read of the Object Inheritance section of the PHP manual. Yes, there's a lot of information in http://us2.php.net/oop, but it may help you think about what you can get out of OOP.
here's what you can do:
class A{
public function methodOfA (){
echo "this is a method of A (and therefore also of B)";
}
}
class B extends A{
public function methodOfB (){
echo "this is a method of B";
// you can do {$this->methodOfA ()} if you want because all of A is inherited by B
}
}
$a = new A (); // $a is an A
$a->methodOfA (); // this is OK because $a is an A
// can't do {$a->methodOfB ()} because $a is not a B
$b = new B (); // $b is a B, and it is also an A, because B extends A
$b->methodOfB (); // ok because $b is a B
$b->methodOfA (); // ok becuase $b is an A
Of course, there's much more. There's a good OOP section in the php manual (in artlung's answer).

Reference and Overwriting

I have:
class A{
public $name = 'A';
public $B;
public function B_into_A($b)
{
$this->B = $b;
}
}
class B{
public $name = 'B';
public $A;
public function new_A_into_B($a)
{
$this->A = new $a;
}
}
$a = new A;
$b = new B;
$a->B_into_A($b);
$b->new_A_into_B('A');
Is this a good way to insert another class inside a "main" class at the beginning of the runtime?
Should I use references?
(Background: I currently work on a MVC framework in which I have to handle many classes within some main classes e.g. bootstrapper, wrapper, modules, adapter etc.)
Yes and No...
Your first function call was fine, I would just use a more standard name:
$a = new A;
$b = new B;
$a->setB($b); // B_into_A is a little bit of a whacky function name
Your second call, it doesn't really make sense to pass a string and then create the object (Unless you're looking for some sort of factory). If you want B to own A:
$b->new_A_into_B( new A );
public function new_A_into_B($a)
{
$this->A = $a;
}
Again i don't like the name.. Id probably go with setA() there as well.
Passing an object instead of its class name makes sense because then it is easier for the garbage collector to guess when it is not needed anymore.
<?php
class A {
public $B;
}
class B {
public $A;
}
$a = new A;
$b = new B;
$a->B = $a;
$b->A = $b;
Furthermore, I'd try to get rid of the setter methods. In practice the only benefit they provide is to validate input. Since it's not the case here, I'd advise you to directly assign the classes.
You asked "Should I use references?". Actually all objects are passed by reference since PHP5. The only way to get an exact copy of them is to use the clone keyword.
By the way, you do not need to store the class name within each object. Just use get_class().

Categories