Can a class instantiate another class? (PHP) - php

I tried this and I get an error when I try to instantiate class "first" inside of class "second".
The commented sections inside of class "second" cause errors.
class first {
public $a;
function __construct() {
$this->a = 'a';
}
}
class second {
//$fst = new first();
//public showfirst() {
//$firsta = $this->first->a;
// echo "Here is first \$a: " . $firsta;
//}
}
EDIT:
This results in a server error even though all I have in class "second" is the instantiation of class "first".
class second {
$fst = new first();
//public showfirsta() {
// $firsta = $this->fst->a;
// echo "Here is first \$a: " . $firsta;
//}
}

try this:
class First {
public $a;
public function __construct() {
$this->a = 'a';
}
public function getA() {
return $this->a;
}
}
class Second {
protected $fst;
public function __construct() {
$this->fst = new First();
}
public function showfirst() {
$firsta = $this->fst->getA();
echo "Here is first {$firsta}";
}
}
$test = new Second();
$test->showfirst();

$fst = new first();
You cannot declare a variable that instantiates a new class outside of a function. The default value cannot be variable. It has to be a string, a number, or possibly an array. Objects are forbidden.
public showfirst() {
You forgot the word function in there.
$firsta = $this->first->a;
You have no class variable $first declared. You named it $fst and would reference it as $this->fst.
echo "Here is first \$a: " . $firsta;
}
For your purposes (whatever those may be):
class second {
public function showfirst() {
$fst = new first();
$firsta = $fst->a;
echo "Here is first \$a: " . $firsta;
}
}

You can instantiate a class inside another. In your case, in your both example you keep referring to the wrong variable. Also, you can't assign a class in the declaration of a property:
class second {
public $fst;
public function showfirsta() {
$this->fst = new first();
$firsta = $this->fst->a;
echo "Here is first \$a: " . $firsta;
}
}

Related

Confusion with constructor function in PHP

Why I am able to use properties in constructor function without being defined in the class, Please read my code below.
<?php
class TV
{
public function __construct($m, $v)
{
$this->model = $m;
$this->volume = $v;
}
}
$tv_one = new TV("Samsung", 6);
echo $tv_one->model."<br><br>";
echo $tv_one->volume;
?>
Have a look at this code also. I am able to share private property outside the class. Just go throuh this code-
<?php
class TV
{
private $model = "Samsung";
private $volume = 2;
public function volumeUp()
{
return $this->volume++;
}
public function volumeDown()
{
return $this->volume--;
}
public function __construct($m, $v)
{
$this->model = $m;
$this->volume = $v;
}
}
class PlasmaTv extends TV
{
public $plasma = true;
public function hello()
{
return "I am new " . $this->model . " and my default volume is " . $this->volume . ".";
}
public function __construct($m, $v, $p)
{
$this->model = $m;
$this->volume = $v;
$this->plasma = $p;
}
}
$plasma = new PlasmaTv("Soni", 6, true);
echo $plasma->model."<br><br>";
echo $plasma->volume."<br><br>";
echo $plasma->plasma;
echo $plasma->hello();
?>
PHP doesn't require you to declare properties. Just assigning to a property will create it as a public property. So when the first constructor does:
$this->model = $m;
that creates a model property in the object.
In your PlasmaTv class, the model and volume properties are not the same as the ones in the parent class TV, because the properties in the parent are private and can't be accessed in the child. If you do:
$plasma->volumeUp();
echo $plasma->volume;
it will print 6, not 7, because volumeUp() incremented a different property than the public property in PlasmaTv.
If you want to share the properties between the child and parent, declare them protected. But then you won't be able to use $plasma->volume from outside the classes.

PHP how set default value to a variable in the class?

class A{
public $name;
public function __construct() {
$this->name = 'first';
}
public function test1(){
if(!empty($_POST["name"]))
{
$name = 'second';
}
echo $name;
}
$f = new A;
$f->test1();
Why don't we get first and how set right default value variable $name only for class A?
I would be grateful for any help.
You can use a constructor to set the initial values (or pretty much do anything for that matter) as you need to like this:
class example
{
public $name;
public function __construct()
{
$this->name="first";
}
}
Then you can use these default values in your other functions.
class example
{
public $name;
public function __construct()
{
$this->name="first";
}
public function test1($inputName)
{
if(!empty($inputName))
{
$this->name=$inputName;
}
echo "The name is ".$this->name."\r\n";
}
}
$ex=new example();
$ex->test1(" "); // prints first.
$ex->test1("Bobby"); // prints Bobby
$ex->test1($_POST["name"]); // works as you expected it to.
you have two options to set the default values for the class attributes:
Option 1: set at the parameter level.
class A
{
public $name = "first";
public function test1()
{
echo $this->name;
}
}
$f = new A();
$f->test1();
Option 2: the magic method __construct() always being executed each time that you create a new instance.
class A
{
public $name;
public function __construct()
{
$this->name = 'first';
}
public function test1()
{
echo $this->name;
}
}
$f = new A();
$f->test1();
Use isset() to assign a default to a variable that may already have a value:
if (! isset($cars)) {
$cars = $default_cars;
}
Use the ternary (a ? b : c) operator to give a new variable a (possibly default) value:
$cars = isset($_GET['cars']) ? $_GET['cars'] : $default_cars;

Pass variables from class instance to its extended method

I'm trying to pass a variable to a method in an extended class, but it's not working.
Here's the sample code:
class set2 extends set1
{
function Body($variable) {
}
}
$start2 = new set2();
$start2->Body('some text');
The last line is the part I'm trying to get to work. I'm not sure if I should have a constructor instead to do it or how it's best to get it to work.
I figured it out. I just added a public variable instead and passed its value like this:
class set2 extends set1
{
public $variable = NULL;
function Body() {
echo $this->variable;
}
}
$start2 = new set2();
$start2->variable = 'Some Text';
Three different ways of doing what I think you're trying to do:
class set1
{
protected $headVariable;
function Head() {
echo $this->headVariable;
}
function Body($variable) {
echo $variable;
}
function Foot() {
echo static::$footVariable;
}
}
class set2 extends set1
{
protected static $footVariable;
function Head($variable) {
$this->headVariable = $variable;
parent::Head();
}
function Body($variable) {
parent::Body($variable);
}
function Foot($variable) {
self::$footVariable = $variable;
parent::Foot();
}
}
$start2 = new set2();
$start2->Head('some text');
$start2->Body('some more text');
$start2->Foot('yet more text');

get a list of all variables defined outside a class by user

i have something like this:
class foo
{
//code
}
$var = new foo();
$var->newVariable = 1; // create foo->newVariable
$var->otherVariable = "hello, im a variable"; //create foo->otherVariable
i can get in class foo a list of all variables defined outside by user (newVariable, otherVariable,etc)? Like this:
class foo
{
public function getUserDefined()
{
// code
}
}
$var = new foo();
$var->newVariable = 1; // create foo->newVariable
$var->otherVariable = "hello, im a variable"; //create foo->otherVariable
var_dump($var->getUserDefined()); // returns array ("newVariable","otherVariable");
Thanks!.
Yes, using get_object_vars() and get_class_vars():
class A {
var $hello = 'world';
}
$a = new A();
$a->another = 'variable';
echo var_dump(get_object_vars($a));
echo '<hr />';
// Then, you can strip off default properties using get_class_vars('A');
$b = get_object_vars($a);
$c = get_class_vars('A');
foreach ($b as $key => $value) {
if (!array_key_exists($key,$c)) echo $key . ' => ' . $value . '<br />';
}
What is your goal? Imo it's not very good practice (unless you really know what you are doing). Maybe it's good idea consider create some class property like "$parameters" and then create setter and getter for this and use it in this way:
class foo {
private $variables;
public function addVariable($key, $value) {
$this->variables[$key] = $value;
}
public function getVariable($key) {
return $this->variables[$key];
}
public function hasVariable($key) {
return isset($this->variables[$key]);
}
(...)
}
$var = new foo();
$var->addVariable('newVariable', 1);
$var->addVariable('otherVariable', "hello, im a variable");
And then you can use it whatever you want, for example get defined variable:
$var->getVariable('otherVariable');
To check if some var is already defined:
$var->hasVariable('someVariable')
get_class_vars() http://php.net/manual/en/function.get-class-vars.php
You question is not clear though.
$var->newVariable = 1;
there are two possible contex of above expression
1) you are accessing class public variables.
like
class foo
{
public $foo;
public function method()
{
//code
}
}
$obj_foo = new foo();
$obj_foo->foo = 'class variable';
OR
2) you are defining class variable runtime using _get and _set
class foo
{
public $foo;
public $array = array();
public function method()
{
//code
}
public function __get()
{
//some code
}
public function __set()
{
// some code
}
}
$obj_foo = new foo();
$obj_foo->bar= 'define class variable outside the class';
so in which context your question is talking about?

How to instantiate object of $this class from within the class? PHP

I have a class like this:
class someClass {
public static function getBy($method,$value) {
// returns collection of objects of this class based on search criteria
$return_array = array();
$sql = // get some data "WHERE `$method` = '$value'
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result)) {
$new_obj = new $this($a,$b);
$return_array[] = $new_obj;
}
return $return_array;
}
}
My question is: can I use $this in the way I have above?
Instead of:
$new_obj = new $this($a,$b);
I could write:
$new_obj = new someClass($a,$b);
But then when I extend the class, I will have to override the method. If the first option works, I won't have to.
UPDATE on solutions:
Both of these work in the base class:
1.)
$new_obj = new static($a,$b);
2.)
$this_class = get_class();
$new_obj = new $this_class($a,$b);
I have not tried them in a child class yet, but I think #2 will fail there.
Also, this does not work:
$new_obj = new get_class()($a,$b);
It results in a parse error: Unexpected '('
It must be done in two steps, as in 2.) above, or better yet as in 1.).
Easy, use the static keyword
public static function buildMeANewOne($a, $b) {
return new static($a, $b);
}
See http://php.net/manual/en/language.oop5.late-static-bindings.php.
You may use ReflectionClass::newInstance
http://ideone.com/THf45
class A
{
private $_a;
private $_b;
public function __construct($a = null, $b = null)
{
$this->_a = $a;
$this->_b = $b;
echo 'Constructed A instance with args: ' . $a . ', ' . $b . "\n";
}
public function construct_from_this()
{
$ref = new ReflectionClass($this);
return $ref->newInstance('a_value', 'b_value');
}
}
$foo = new A();
$result = $foo->construct_from_this();
Try using get_class(), this works even when the class is inherited
<?
class Test {
public function getName() {
return get_class() . "\n";
}
public function initiateClass() {
$class_name = get_class();
return new $class_name();
}
}
class Test2 extends Test {}
$test = new Test();
echo "Test 1 - " . $test->getName();
$test2 = new Test2();
echo "Test 2 - " . $test2->getName();
$test_initiated = $test2->initiateClass();
echo "Test Initiated - " . $test_initiated->getName();
When running, you'll get the following output.
Test 1 - Test
Test 2 - Test
Test Initiated - Test

Categories