This question already has an answer here:
PHP array of non-primitive class as function parameter
(1 answer)
Closed 4 years ago.
I'm quite new with PHP. I'm having problems declaring an object as array for function parameter. In Java, I simply use public void methodName (List<Object> listVariableName){} for passing a list of many Objects.
I did some research in PHP and one of the answers suggested to put array in method parameter declaration like so function myFunction($a, array Object $obj){}
Currently, I have a class named Lesson
class Lesson implements JsonSerializable{
private $lessonId;
private $lessonNo;
private $lessonTitle;
private $isLessonActive;
private $isLessonRemoved;
//getters and setter here....
}
Then I'm trying to declare a method called addTopicLesson
function addTopicLesson(Topic $topic, array Lesson $lesson){
}
But, I'm getting an error in array Lesson $lesson
There's 1 topic and MANY lessons. How can I go about implementing or defining the method signature?
I found this but I'd like to know if there's a better approach than to call itself.
I'd appreciate any suggestion.
Thank you.
List<T> is not an array. It's a list utilizing generic type mechanism.
There are no generics in PHP. You can only typehint an array but you cannot control what's inside it at the level of method declaration.
function addTopicLesson(Topic $topic,array $lessons)
{
foreach($lessons as $lesson)
{
addLesson($page);
}
}
function addLesson(Lesson $lesson)
{
}
Related
This question already has answers here:
Why is type hinting necessary in PHP?
(6 answers)
Closed 4 years ago.
I am not able to understand what is the meaning of having any model or interface object into the method parameters.
For example,
public function checkRights(CommentInterface $comment)
{
return true;
}
so here what does CommentInterface do? why we are not only passing $comment here? How do you name this kind of thing in programming language?
I am new to object oriented php
Thanks.
This is called as Type Hinting.
Type hinting forces you to only pass objects of a particular type. This prevents you from passing incompatible values, and creates a standard if you're working with a team etc.,
check the following example:
class Profile {
private $setting;
public function __construct(Setting $setting)
{
$this->setting = $setting;
}
}
Because we need to use the $setting object inside the function, we inject/pass/type-hint it as a parameter.
This question already has answers here:
Dynamic static method call in PHP?
(9 answers)
Closed 6 years ago.
I have a couple of methods whose returns are being cached, and the cache key is the name of the method itself.
For instance, if this is my class
class tester {
static function test() {
$data = build_data();
cache(__METHOD__, $data);
}
}
The cache key value is tester::test.
I am implementing functionality to warm the cache. If I have all the cache keys, I could just call them one by one.
foreach ( $keys as $key ) {
$key();
}
But apparently, I can't call a string like 'tester::test' in this manner
Fatal error: Call to undefined function tester::test() ...
Do I have to do string parsing, to pull apart the class name and method, and then call them like $class::$method()? Or is there a simpler way to do it?
Thanks to Michael Lihs for linking the question in their comment; it turns out that call_user_func() does what I'm looking for.
This question already has answers here:
Best way to do multiple constructors in PHP
(25 answers)
Closed 8 years ago.
In Java, I enjoy the flexibility of having 1 to x number of constructors depending my need and the number of properties/attributes my class have.
class Foo{
private int id;
private boolean test;
private String name;
public Foo(){
}
public Foo(int id){
this.id=id;
}
public Foo(boolean test){
this.test=test;
}
public Foo(int id, boolean test){
this.id=id;
this.test=test;
}
}
Unlike in PHP I can only have one constructor from what I have learnt so far.
class Foo{
private $id;
private $test;
private $name;
function __construct() {
}
}
Or
class Foo{
private $id;
private $test;
private $name;
function __construct($id, $test, $name) {
$this->id=$id;
$this->test=$test;
$this->name=$name;
}
}
Or any other combinations;
What I do:
Most time I prefer populating these properties using the getters and setters but this can result in writing a lot of codes for classes with some number of properties. I think there could be some better approaches:
My questions are two:
Why can't I overload PHP constructors? I want to know reason behind this limitation
What is the best why of populating a PHP object properties?
Two things:
You can use func_get_args() to retrieve and inspect the passed arguments. Note that PHP doesn't even check the number of arguments, so it can be function foo() while inside many arguments are handled.
Use a so-called fluent interface, i.e. a chain of setters that each return $this. This then becomes Foo::create()->setId(42)->setName('blah'), which is almost as readable as Pythons named parameters.
This question already has answers here:
PHP: Static and non Static functions and Objects
(5 answers)
Closed 8 years ago.
I am still learning OOP PHP and I keep swapping and changing between the following way of calling methods within an object
$obj = new Model();
$obj->method($param);
against
Model::method($params);
I understand the difference when I within the method as I can use $this in the first example, and I have to use self:: in the second.
Which is the correct way and what are the reasons of using each way
The reason I ask is I cannot find a suitable search term to research. I am currently reading a book on OOP and it will probably tell at some point, but would be nice to know now.
Foo::bar() calls the static class method, while $foo->bar() calls the instance method on an object. These are two completely different things. You do not need an object instance to call Foo::bar(), and in fact you do not have access to instance data when doing so. Foo::bar() is essentially nothing else but a regular function call like bar(), except that the function is attached to a class.
Instance methods act on a specific object instance:
class User {
protected $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public static function hi() {
// no access to $this->name here, since static
// methods are not bound to specific instances
echo 'Hi';
}
}
$dave = new User('Dave');
$mary = new User('Mary');
echo $dave->getName(); // Dave
echo $mary->getName(); // Mary
User::hi(); // Hi
Unless you understand this, you know nothing about OOP.
First example is a non-static call to the method, second a static call.
The first is better if you want to access private variables of your Model, second is better if you use the method like a normal function.
In general you should declare methods of the first type as static (public static function method(){}).
First case is invocation of method on class instance, second case is call of static method.
See http://php.net/manual/en/language.oop5.static.php
There is no "proper" way because both call types serve different purposes.
The first call type is the standard way of handling objects: You initialize a concrete instance of a class. This instance can have its own internal values and each instance can use these values to create a different result when you call the method with the same parameter.
The second call type is called static and operates directly on the class, there is no instance (hence no $this). There are some use cases for it, see this answer for Java, it's the same for PHP.
This question already has answers here:
Passing an instance method as argument in PHP
(3 answers)
Closed 9 years ago.
I have a class in PHP like this:
class RandomNumberStorer{
var $integers = [];
public function store_number($int){
array_push($this->integers, $int);
}
public function run(){
generate_number('store_number');
}
}
...elsewhere I have a function that takes a function as a parameter, say:
function generate_number($thingtoDo){
$thingToDo(rand());
}
So I initialise a RandomNumberStorer and run it:
$rns = new RandomNumberStorer();
$rns->run();
And I get an error stating that there has been a 'Call to undefined function store_number'. Now, I understand that that with store_number's being within the RandomNumberStorer class, it is a more a method but is there any way I can pass a class method into the generate_number function?
I have tried moving the store_number function out of the class, but then I then, of course, I get an error relating to the reference to $this out of the context of a class/ instance.
I would like to avoid passing the instance of RandomNumberStorer to the external generate_number function since I use this function elsewhere.
Can this even be done? I was envisaging something like:
generate_number('$this->store_number')
You need to describe the RandomNumberStore::store_number method of the current instance as a callable. The manual page says to do that as follows:
A method of an instantiated object is passed as an array containing an
object at index 0 and the method name at index 1.
So what you would write is:
generate_number([$this, 'store_number']);
As an aside, you could also do the same in another manner which is worse from a technical perspective, but more intuitive:
generate_number(function($int) { $this->store_number($int); });