Passing class from another class or dependency injection - php

I'm having difficulties to understand the given code and the reason behind dependency injection. I've got the following error:
Uncaught Error: Call to undefined method Question::getFullName() in C:\xampp\htdocs\OOP\Index.php:10 Stack trace: #0 {main} thrown in C:\xampp\htdocs\OOP\Index.php on line 10.
Even if I instantiate an object of the Author class in the constructor, I keep getting a string in the Question class once I try to use getQuestion().
require 'Author.php';
class Question {
private $author;
private $question;
public function __construct($question, Author $author) {
$this->author = $author;
$this->question = $question;
}
public function getAuthor() {
$firstname = $this->author->getFirstName();
$lastname = $this->author->getLastName();
$fullaname = $firstname . $lastname;
return $this;
}
public function getQuestion() {
return $this->question;
}
}
<?php
class Author {
private $firstName;
private $lastName;
private $fullName;
public function __construct($firstName, $lastName) {
$this->firstName = $firstName;
$this->lastName = $lastName;
}
public function getFirstName() {
return $this->firstName;
}
public function getLastName() {
return $this->lastName;
}
public function getFullName() {
return $this->fullName = $this->firstName." ".$this->lastName;
}
}
require 'Question.php';
$question = new Question("What is the author's name?", new Author("josel", "parayno"));
echo $question->getQuestion();
echo $question->getFullName();

$question really does not have getFullName method. Method getFullName exists in class Author. And after creating and "sending" to Question, when it was created method getFullName available in class Question private $author property.
But if you want to get Athor name by follow code, you need try
$question->getAuthor()->getFullName();
And if you do this, you take error again, becouse in question->getAuthor you return $this, and in this case this is a Question object. For getting author name from question object you should to do follow:
Fix getAuthor like this
public function getAuthor()
{
$firstname = $this->author->getFirstName();
$lastname = $this->author->getLastName();
return $this->author;
}
Rewite call name in you index.php like this
echo $question->getAuthor()->getFullName();

Related

PHP Error: Undefined property '$title'. intelephense (1014)

I am getting the error "Undefined property '$title'. intelephense (1014)" for the employee class.
class User {
// Properties are attributes that belong to a class
public $name;
public $email;
public $password;
public function __construct($name, $email, $password) {
$this->name = $name;
$this->email = $email;
$this->password = $password;
}
function set_name($name) {
$this->name = $name;
}
function get_name() {
return $this->name;
}
}
// Inheritence
class Employee extends User {
public function __construct($name, $email, $password, $title)
{
parent::__construct($name, $email, $password);
$this->title = $title;
}
public function get_title() {
return $this->title;
}
}
$employee1 = new Employee('Sara', 'sara#gmail.com', '123', 'manager');
echo $employee1->get_title;
I am also getting the same error for '$get_title' when I try to echo on the last line.
I was expecting to see the employee's title: 'manager'.
It's not :
echo $employee1->get_title;
but :
echo $employee1->get_title();
Try using an IDE to develop, this will avoid this kind of error thanks to autocompletion. VSCode for example.
Edit: you forgot the declaration of $title in the class Employees

Importing Parent function data in child php oop

I am trying to learn simple method of php oop by calling parent function data in child.
However somewhere I am making mistake.
class name{
var $firstname;
var $lastname;
var $name;
public function name($firstname, $lastname){
$this->firstname=$firstname;
$this->lastname=$lastname;
$this->name=$this->firstname." ".$this->lastname;
return $this->name;
}
}
class sentence extends name{
var $name;
var $letter;
function sentence(){
$this->letter="My name is ";
echo $this->letter.$this->name;
}
}
$name=new name(ABC, Xyz);
$letter=new sentence();
I have created one calls to get name input and another child class to write the sentence. However not able to call the name in child.
a quick fix since thats probably what you want.
<?php
class name {
private $firstname;
private $lastname;
private $name;
private $sentence;
public function __construct($firstname, $lastname){
$this->firstname = $firstname;
$this->lastname = $lastname;
$this->name = $firstname . " " . $lastname;
$this->sentence = "My name is : " . $this->name;
}
public function getName(){
return $this->name;
}
public function getSentence(){
return $this->sentence;
}
}
$instance = new name("test","lastname");
echo $instance->getSentence();
?>
class name
{
public $firstname;
public $lastname;
public $name;
public function name($firstname, $lastname)
{
$this->firstname = $firstname;
$this->lastname = $lastname;
$this->name = $this->firstname.' '.$this->lastname;
return $this->name;
}
}
class sentence extends name
{
public $name;
public $letter;
public function greeting()
{
$this->letter = 'My name is ';
echo $this->letter.$this->name;
}
}
//$name=new name(ABC, Xyz);
$letter = new sentence('ABC', 'Xyz');
$letter->greeting();
Thanks to #ManhNguyen
Are you trying to read the state of variables in a parent class?
That is not how OOP works.
You have to either group together all the variables into one class or pass it trough as an argument to the function you want to have access to the data.
Second of all you don't seem to not be using a __construct function and yet pass variables into the new name() function that is also a NO-NO.

understanding dependency injection in PHP

class Author {
private $firstName;
private $lastName;
public function __construct($firstName, $lastName) {
$this->firstName = $firstName;
$this->lastName = $lastName;
}
public function getFirstName() {
return $this->firstName;
}
public function getLastName() {
return $this->lastName;
}
}
class Question {
private $author;
private $question;
public function __construct($question, Author $author) {
$this->author = $author;
$this->question = $question;
}
public function getAuthor() {
return $this->author;
}
public function getQuestion() {
return $this->question;
}
}
Class author is injected into the constructor of Question class am I correct? but how to call the Question class to get the author's name?
$question = new Question('What is PHP', 'Adam');
$question->getFirstname;
like this? I assume Question class inherited Author class so Question's instance can use the function of Author Class?
Simple
echo $question->getAuthor()->getFirstName();
Think of it this way if it helps
$author = $question->getAuthor();
echo $author->getFirstName();
Also note that you can't construct a Question with the string "Adam", you need to pass an instance of Author
$question = new Question('What is PHP', new Author('Adam', 'Lastname'));
You could create a new method:
class Question
{
// ...
function getAuthorFirstname()
{
return $this->author->getFirstname();
}
}
$question = new Question(.., new Author(..., ...));
echo $question->getAuthorFirstname();
Or, if you don't really care about Law of Demeter or feel that it doesn't apply:
$question = new Question(.., new Author(..., ...));
echo $question->getAuthor()->getFirstname();
In the end it all comes down to striking a balance between information hiding and pragmatism.

PHP data collector engine Fatal Error

I am trying to write a small engine in PHP to handle data but i keep on getting this error:
Fatal error: Class 'Factory\dataHandler' not found in /Applications/MAMP/htdocs/Imperial/lp/php/dataPhraserController.php on line 12
Been now trying to find a way of solving the problem but not luck.....
My code:
DataFactory.php
<?php
namespace Factory;
class dataHandler{
protected $firstName;
protected $lastName;
protected $email;
protected $confirmEmail;
protected $phoneNumber;
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
public function setEmail($email)
{
$this->email = $email;
}
public function setConfirmEmail($confirmEmail)
{
$this->confirmEmail = $confirmEmail;
}
public function setPhoneNumber($phoneNumber)
{
$this->phoneNumber = $phoneNumber;
}
public function getFirstName()
{
var_dump($this->firstName);
}
public function getLastName()
{
return $this->lastName;
}
public function getEmail()
{
return $this->confirmEmail;
}
public function getPhoneNumber()
{
return $this->phoneNumber;
}
}
dataPharserController.php:
<?php
namespace PhraserController;
use Factory\dataHandler;
class DataPhraser
{
private $object;
public function __construct()
{
$this->object = new dataHandler;
}
public function pharseFirstName()
{
if(!isset($_POST['first_name']))
{
$this->object->setFirstName($firstName = null);
var_dump($_POST['first_name']);
}else{
$this->object->setFirstName($firstName = $_POST['first_name']);
}
}
}
$test = new DataPhraser();
$test->pharseFirstName();
The idea is to collect data from a submitted html form, can someone help me.. thx
Place this in one of your config files that are loaded before everything
DEFINE('LIB_DIR', '/path_to_library_dir_of_project/');
function AutoloadDefault($ClassName)
{
$File = LIB_DIR.'/' . $ClassName. '.php';
// echo 'Default:'.$File.'<br/>';
if (file_exists($File))
{
require_once($File);
}
}
spl_autoload_register('AutoloadDefault');
Then just point to right LIB_DIR folder. spl_autoload_register will load the class file

How do I save my Person-class to database, and how to use the constructor in php?

I have created a class Person, who contain a person. Here is my code:
<?php
class Person {
private $age;
private $firstName;
private $lastName;
private $optional;
function __construct($id) {
// Load all settings form database, because the person already exists.
}
function __construct($age, $firstName, $lastName, $optional) {
$this->age = $age;
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->optional = $optional;
}
function setFirstName($name) {
$this->firstName = $name;
}
function setLastName($name) {
$this->lastName = $name;
}
function setOptional($key, $value) {
$optional[$key] = $value;
}
function setAge($age) {
$this->age = $age;
}
function getFirstName() {
return $this->firstName;
}
function getLastName() {
return $this->lastName;
}
function getOptional($key) {
return $optional[$key];
}
function getAge() {
return $this->age;
}
}
?>
First: This person will be created if a new user fill a form on the web page (and stored to database) and this person will also be used when the web app want some information about the current user.
How do I interact this class with the database? I guess that I could create two constructors as I have done (I think that you could do like this in java). The first constructor is for when constructing an already registered user, and therefore it will load all information from the database. The second constructor is for when a new user is registered, and it should send all information to the database. Is this the right way to handle the database?

Categories