This question already has answers here:
PHP json_encode class private members
(9 answers)
Closed 3 days ago.
I have a class:
class A {
protected $nome;
public function getNome() {
return $this->nome . " exemplo";
}
public function setNome($nome) {
$this->nome = $nome;
}
}
When i use the code:
$r = new A();
$r->setNome("My");
json_encode($r);
the code not returns because of the protected property, if the property is public the code returns but does'nt returns correctly.
As per the definition of class, we can access only public members outside class. So make $nome for public
class A {
public $nome;
public function getNome() {
return $this->nome . " exemplo";
}
public function setNome($nome) {
$this->nome = $nome;
}
}
$r = new A(); print_r($r);
$r->setNome("My");
echo json_encode($r);
OR
Return results to json_encode(if you don't make $Nome public), see the example:
$r = new A();
$r->setNome("My");
echo json_encode($r->getNome());
Related
the code is self-explanatory, but the problem is, that I can't override the static variable through method calls, so the static variable of the class gives a value, but the value that I get through the objects is different.
Class dbEntity {
protected static $connection;
private static $name = "dbEntity";
public static function getName() {
return self::$name;
}
public static function setConnection($connection) {
self::$connection = $connection;
}
public static function getConnection() {
return self::$connection;
}
}
Class Patient extends dbEntity {
public static $connection = "patientConnection";
public static $name = "Patient";
}
$p = new Patient();
$p->setConnection("myConnection");
echo $p->getConnection() . "\n"; //myConnection
echo Patient::$connection . "\n"; //patientConnection
echo $p->getConnection() . "\n"; //myConnection
Ulrich is correct, if you change the following lines from self:: to static:: the code works as you're expecting it to.
public static function getName() {
return static::$name;
}
public static function setConnection($connection) {
static::$connection = $connection;
}
public static function getConnection() {
return static::$connection;
}
...
echo $p->getConnection() . "<br>"; //myConnection
echo Patient::$connection . "<br>"; //myConnection
echo $p->getConnection() . "<br>"; //myConnection
You need late static binding, see the official documentation:
https://www.php.net/manual/en/language.oop5.late-static-bindings.php
This question already has answers here:
Are objects in PHP assigned by value or reference?
(3 answers)
Are PHP5 objects passed by reference? [duplicate]
(8 answers)
Closed 2 years ago.
what i want to ask is, why the $character property of Forest class is a reference instance to $character Object not the clone ?
<?php
// example code
Class Ogre
{
protected $position = 0;
protected $name;
public function setPosition($position)
{
$this->position = $position;
}
public function getPosition()
{
return $this->name.' position is at axis '.$this->position.'.';
}
public function setName($name)
{
$this->name = $name;
}
public function walk($step)
{
$this->position += $step;
return $this;
}
public function getInfo()
{
return 'Type: '.self::class.', Name: '.$this->name;
}
}
class Forest
{
protected $character;
public function __construct($character)
{
// var_dump($character);
$character->setPosition(55);
}
public function getName()
{
return 'Theme Name : Forest';
}
}
$character = new Ogre();
$character->setName('Magi');
echo $character->getPosition(); //the position is 0 i've never defined the position
$theme = new Forest($character);
echo $character->getPosition(); //it shows 55 because i defined it inside Forest constructor
I wrote a class
class User {
private $cars = array(); //store class Car 's object
public function getCars()
{
return $this->cars;
}
public function setCars($cars)
{
$this->cars = $cars;
}
}
class Car{
private $model;
public function getModel()
{
return $this->model;
}
public function setModel($model)
{
$this->model = $model;
}
}
$user = new User();
$cars = $user->getCars();
$cars[0]->getModel();
When I try to access getModel() php report "Call to undefined method stdClass::getModel()" .
Is there the best practice to deal with such case?
Edit:I filled the getter and setter. In fact, It's generated by phpstorm.
Edit:I tried again and it works well with the demo code below. The original code is too complicated to show. Maybe I caused by my misunderstanding of copying by value and by reference of array.
Please ignore this question. sorry.
class User {
private $cars = array(); //store class Car 's object
public function getCars()
{
return $this->cars;
}
public function setCars($cars)
{
$this->cars = $cars;
}
}
class Car{
private $model;
public function getModel()
{
return $this->model;
}
public function setModel($model)
{
$this->model = $model;
}
}
$user = new User();
$car = new Car();
$car->setModel("Ford");
$arr = $user->getCars();
array_push($arr,$car);
$user->setCars($arr);
foreach($user->getCars() as $car) {
var_dump($car->getModel());
}
You haven't shown your [Getter Setter ] code. You need to create one with something like:
public function setCars($val){
$this->cars = $val;
}
public function getCars(){
return $this->cars;
}
The same applies for getModel()
I'm wondering if its possible to switch the visibility in PHP. Let me demonstrate:
class One {
function __construct($id){
if(is_numeric($id)){
//Test function becomes public instead of private.
}
}
private function test(){
//This is a private function but if $id is numeric this is a public function
}
}
Is such thing even possible?
I would use an abstract class with two implementing classes: One for numeric and one for non-numeric:
abstract class One {
static function generate($id) {
return is_numeric($id) ? new OneNumeric($id) : new OneNonNumeric($id);
}
private function __construct($id) {
$this->id = $id;
}
}
class OneNumeric extends One {
private function test() {
}
}
class OneNonNumeric extends One {
public function test() {
}
}
$numeric = One::generate(5);
$non_numeric = One::generate('not a number');
$non_numeric->test(); //works
$numeric->test(); //fatal error
It can be faked up to a point with magic methods:
<?php
class One {
private $test_is_public = false;
function __construct($id){
if(is_numeric($id)){
$this->test_is_public = true;
}
}
private function test(){
echo "test() was called\n";
}
public function __call($name, $arguments){
if( $name=='test' && $this->test_is_public ){
return $this->test();
}else{
throw new LogicException("Method $name() does not exist or is not public\n");
}
}
}
echo "Test should be public:\n";
$numeric = new One('123e20');
$numeric->test();
echo "Test should be private:\n";
$non_numeric = new One('foo');
$non_numeric->test();
I haven't thought about the side effects. Probably, it's only useful as mere proof of concept.
Bellow is a PHP script.
I tried to implement the Observer pattern (without MVC structure)... only basic.
The error which is encountered has been specified in a comment.
First I tried to add User objects to the UsersLibrary repository. There was a error such as User::update() does not exists or something.
Why is that error encountered? What fix should be applied and how?
interface IObserver {
public function update(IObservable $sender);
}
interface IObservable {
public function addObserver(IObserver $obj);
public function notify();
}
class UsersLibrary implements IObservable {
private $container;
private $contor;
//private $z;
public function __construct() {//IObserver $a) {
$this->container = array();
$this->contor = 0;
echo "<div>[constructing UsersLibrary...]</div>";
$this->addObserver(new Logger());
//$this->z = $a;
}
public function add($obj) {
echo "<div>[adding a new user...]</div>";
$this->container[$this->contor] = $obj;
$this->contor++;
$this->notify();
}
public function get($index) {
return $this->container[$index];
}
public function addObserver(IObserver $obj) {
$this->container[] = $obj;
}
public function notify() {
echo "<div>[notification in progress...]</div>";
foreach($this->container as $temp) {
//echo $temp;
#################################################################
$temp->update(); //--------ERROR
//Fatal Error: Call to a member function update() on a non-object.
#################################################################
}
//$this->container[0]->update();
//$this->z->update($this);
}
}
class User {
private $id;
private $name;
public function __construct($id, $name) {
$this->id = $id;
$this->name = $name;
}
public function getId() {
return $this->id;
}
public function getName() {
return $this->name;
}
}
class Logger implements IObserver {
public function __construct() {
echo "<div>[constructing Logger...]</div>";
}
public function update(IObservable $sender) {
echo "<div>A new user has been added.</div>";
}
}
$a = new UsersLibrary(); //new Logger());
//$a->add(new User(1, "DemoUser1"));
//$a->add(new User(2, "DemoUser2"));
$a->add("Demo");
echo $a->get(0);
//echo $a->get(0)->getName();
Your User class is not implementing interface IObserver and therefore is not forced to have the method update().
You have to instantiate a new User() in order to add it to the UsersLibrary:
$library = new UsersLibrary();
$user = new User(1, "Demo");
$library->add($user);
Also, you are mixing Users and Loggers into your UsersLibrary container. Maybe think about separating the containers for them?
You are passing a string instead of an object in your $a->add() call. You should either pass in an object, or alter the code in UserLibrary::add() to wrap it's argument in an appropriate object (or do an object lookup of it sees a string, for instance find a user with that name).
$user = new User(1, "Demo");
$a = new UsersLibrary();
$a->add($user);