Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Given the following example:
<?php
class Model
{
private $data = [];
public function __set($property, $value)
{
$this->data[$property] = $value;
}
public function __get($property)
{
if(isset($this->data[$property]))
{
return $this->data[$property];
}
throw new Exception("Error trying to access undefined data");
}
public static function all()
{
// returns all models
}
public function save()
{
// save something to database
}
}
And this class:
class Person extends Model
{
protected $name;
public static function migrateNamesToUppercase()
{
foreach(self::all() as $person)
{
$person->name = strtoupper($person->name);
$person->save();
}
}
}
Inside static method "Person::migrateNamesToUppercase" $person->name is null.
Outside static method "Person::migrateNamesToUppercase" (new Person())->name throws the expected exception.
When the class instance lives inside a static method of the same class PHP just assumes it has access to a protected property and neither __get or __set is executed! Sadly, same thing happens to private properties.
My question is: Shouldn't the behavior of the instances be the same in both contexts? Is this a known bug or just a failed PHP OO implementation?
I googled about it and found nothing
__get() is utilized for reading data from inaccessible properties.
See the PHP manual for details
It's working as defined. $name is accessible from the object so it does not use the method. If $name were private and defined in the parent class it would be inaccessible and so would use the method.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have a weird problem in PHP. I have two classes, one extending another. The problem is that i when I try to access a variable in the parent class (via a getVar() method), it returns undefined, even though it had been already defined in the parent's constructor.
class HttpClient
{
private $errorList;
public function __construct()
{
$errorList = [];
}
public function getHttpErrorList() { return $errorList; }
//...
}
class Twitter extends HttpClient
{
public function __construct()
{
parent::__construct();
//..
}
public function getMessages()
{
//...
var_dump($this->getHttpErrorList()); //returns undefined variable!
}
What is the cause of this problem and how do I solve it?
Defining $errorList=[] inside your constructor is defining a local variable to the constructor. I.e. variable $errorList is undefined in method getHttpErrorList() - if you want access to $errorList at the object level, you need to change it to $this->errorList inside your constructor and in method getHttpErrorList().
<?php
class HttpClient
{
private $errorList;
public function __construct()
{
$this->errorList = []; // change to $this->errorList
}
public function getHttpErrorList() { return $this->errorList; } // change to $this->errorList
//...
}
class Twitter extends HttpClient
{
public function __construct()
{
parent::__construct();
//..
}
public function getMessages()
{
//...
var_dump($this->getHttpErrorList()); //outputs array(0) {}
}
}
$twit = new Twitter();
$twit->getMessages(); // output: array(0) { }
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
So, I have this class that gets used over and over again throughout my app. This is just an example, not what's actually needed to be done:
File A:
class Names {
public function first() {
echo 'Bob';
}
}
That file is autoloaded into my app using spl_autoload_register and used all throughout in other pages/classes:
File B:
class LastNames {
public function __construct() {
$this->first = new Names();
}
public function last() {
echo $this->first->first().' Smith';
}
}
$names = new LastNames();
echo $names->last(); // Bob Smith
I have many files that instantiate the class Names inside the constructor.
Does this cause much of a hit on performance?
Should I be using static function instead of public function?
Is there a better way to reuse the functions inside Names over and over again inside different classes?
You have several options, using static function is one of them :
class LastNames {
public static function foo(){
// do stuff
}
}
Or you can use a singleton :
class LastNames {
private static $instance = null;
private function __construct(){
// do stuff
}
public function foo(){
// do stuff
}
public static function getInstance(){
if ( !self::$instance ){
self::$instance = new LastNames();
}
return self::$instance;
}
}
And then you can call it with :
$lastnames = LastNames::getInstance();
$lastnames->foo();
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have the following code in place.
Interface Vehicle which has a method calculateDistance.
Class Car implements Vehicle
Class Bicycle implements Vehicle
Class MotorCycle implements Vehicle
What I want to do next is a method in my controller that calls every class that implements Vehicle and get the values from calculateDistance.
What would be the best way/design pattern to achieve this?
At this moment I am just calling all the classes that implement the interface Vehicle (via ReflectionClass) and loop over them to call this method.
The best way is to implement CompilerPass. Here is an example .
So, create a registry class (TransportChain class in that example), interface, and all classes that implements that interface, define them as services and give them tag name.
After that, you can call that registry service in your action, and call your desired method by each service.
Basic example:
interface
interface SomeInterface {
public function doSomething();
}
Service 1:
class First implement SomeInterface {
public function doSomething() {
// do smth
}
}
Service 2:
class Second implement SomeInterface {
public function doSomething() {
// do smth
}
}
Registry class:
class MyRegistry
{
private $services = [];
public function addMyService($service)
{
$this->services[] = $service;
}
public function all()
{
return $this->services;
}
}
CompilerPass:
...
$myServices = $container->findTaggedServiceIds('my_tag');
if (empty($myServices)) {
return;
}
$registry = $container->getDefinition('my_registry');
foreach ($myServices as $key => $myService) {
$registry->addMethodCall('add', [new Reference($key)]);
}
...
After clearign the cache, you can call them in your action:
...
foreach ($this->get('my_registry')->all() as $myService) {
$myService->doSomething();
}
...
The whole other stuff, like declaring services, give them tag name, registering your compiler pass has been written here.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
How to create public php class object inside a another class?.
I have a class called
page.php
and also
Main.php
and
Content.php
I want to call Main.php and Content.php class inside the page.php class. What is the correct way to do this.
I tried this, but not working :( . Please help.
<?php
class Page
{
public $main;
public $content;
function __construct()
{
$main=new Main_Model();
$content=new Content_Model();
}
public function Menu()
{
$load_menu=$content->Load_Menu();
...
...
}
}
?>
I can only assume you are new to OOP.
But the issue resides within you needing to access the variables from the global scope.
I am also making the assumption that you are using a framework that provides auto-loading and that these classes are actually accessible.
class Page
{
private $main;
private $content;
function __construct()
{
$this->main=new Main_Model();
$This->content=new Content_Model();
}
public function Menu()
{
$load_menu=$this->content->Load_Menu();
...
...
}
}
That should solve everything for you. Also you should define your variables as private unless you plan on exposing them for use in other places as a public interface. And even then there is discussion on using methods to access private variables.
This should fix you're issue and I've changed/fixed a few other bits like public/private variables etc. As others have said you're missing the $this-> in your construct()
<?php
class Main_Model {
public function Load_Menu() {
return "This is the menu function";
}
}
class Content_Model {
public function Load_Content() {
return "This is the main content function";
}
}
class Page {
private $mainmenu;
private $content;
function __construct() {
$this->mainmenu = new Main_Model();
$this->content = new Content_Model();
}
function Menu() {
return $this->mainmenu->Load_Menu();
}
function Content() {
return $this->content->Load_Content();
}
}
$page = new Page();
echo $page->Menu();
echo "<br />";
echo $page->Content();
?>
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
class Index extends Controller{
public function first_index(){
parent::__construct();
public $name = 'tiko';
$this -> view -> render('index/template','index/index');
}
}
Error:
Parse error: syntax error, unexpected T_PUBLIC in
Z:\home\localhost\www\3ddproc.ru\controllers\index.php on line 6
Line 6 - public $name = 'tiko';
you should set $name inside the class, not the function.
in the function you can set it to have any value you want, but declaration must be in the class root scope
class Index extends Controller{
public $name;
public function first_index() {
parent::__construct();
$this->name = 'tiko';
$this -> view -> render('index/template','index/index');
}
}
Public, protected, and private provide scope resolution for class functions (methods) and member variables remove public $name = 'tiko'; from inside the function instead put outside or before the function
class Index extends Controller{
public $name = 'tiko';
public function first_index(){
parent::__construct();
$this -> view -> render('index/template','index/index');
}
}