PHP OOP: Accessing Variables - php

I have the following "Student" Class:
class Student {
public $user_id;
public $name;
public function __construct($user_id) {
$info = $this->studentInfo($user_id);
$this->name = $info['name'];
$this->is_instructor = $info['is_instructor'];
$this->user_id = $info['id'];
}
public static function studentInfo($id) {
global $db;
$u = mysql_fetch_array(mysql_query("SELECT * FROM $db[students] WHERE id='$id'"));
if($u) {
return $u;
}
}
public static function getCoursesByInstructor() {
global $db;
return mysql_query("SELECT courses.*, course_types.name FROM $db[courses] as courses
JOIN $db[course_types] as course_types ON courses.course_type_id=course_types.id
WHERE instructor_id='$this->user_id'");
}
}
I'm trying to do:
$u = new Student(1);
$courses = $u->getCoursesByInstructor();
But am getting the following error:
Fatal error: Using $this when not in object context in /Applications/MAMP/htdocs/flight1/phpincludes/classes/students.class.php on line 54

You're getting that error because you're function is a static function, and therefore you cannot use the $this pointer within it because it supposed to point to an object. So just remove the static keyword from your function definitions.

You are using static methods non-statically. Static methods are only bound to its class, but not to an object, thus $this is not available. This especially means, that $this->userid, that you use in getCoursesByInstructor(), is not valid. I recommend to make the method non-static.
public function getCoursesByInstructor() { /* your code here */ }

Remove the static keyword from the functions you declared inside your Student class.
The static keyword is, simply put, used to indicate a function that is accessible without the need of creating an instance of that class. On the other hand, $this is used to refer to class instance variables. That's why those two don't go well togheter, you're trying to access an instance variable (by using $this) in a static context.

The issue with your code is you are requesting $this inside your static function. See this. You have $this->user_id inside the query.
return mysql_query("SELECT courses.*, course_types.name FROM $db[courses] as courses
JOIN $db[course_types] as course_types ON courses.course_type_id=course_types.id
WHERE instructor_id='$this->user_id'");
To fix this issue you have to modify this function. I can suggest you following way.
public static function getCoursesByInstructor($userID) {
global $db;
return mysql_query("SELECT courses.*, course_types.name FROM $db[courses] as courses
JOIN $db[course_types] as course_types ON courses.course_type_id=course_types.id
WHERE instructor_id='$userID'");
}
And you have to change your other functions with the same theory.
Cheers !

Related

With or without $this in PHP [duplicate]

This question already has answers here:
What does the variable $this mean in PHP?
(11 answers)
Closed 4 years ago.
I am new in OOP PHP. Why do we have to use $this reference, when the code is working without it too?
If I delete both $this (before ->sql) from this code fragment, the modification is work as well. Although I read about it, I still don't understand what is $this in the given method.
class blogs{
private $servername = "localhost";
private $username = "root";
private $password = "";
private $dbname = "asd";
private $conn = "";
private $result = "";
private $row = "";
private $sql = "";
public function cmd_update(){
$this->sql = "UPDATE
blogs
SET
`name` = '".$_GET['input_name']."',
`date` = '".date('Y-m-d H:m:s')."',
WHERE
id = ".$_GET['input_modifying_id']."
";
if ($this->conn->query($this->sql) === TRUE) {
echo "Successfully modified!";
} else {
echo "Modifying Unsuccessful!";
}
}
$this refers to the current object - in this case, $this is shorthand for the blogs class.
Let's take this example class:
class Foo
{
protected $a;
public function __construct($a)
{
$this->a = $a;
}
public function getA()
{
return $this->a;
}
}
Here I'm simply assigning $a to whatever gets passed to a new Foo instance and creating a public-accessible function to return $a.
We use $this to refer to what we're currently in, $this->a is the protected $a.
This is a really handy feature for developers as it means we don't have to create our own way of getting the instance without redeclaration. It also means we can use templating for easier use. E.g.
class Foo
{
public function sayHi()
{
return 'hello world';
}
}
and
class Bar extends Foo
{}
because public functions are well.. public we can access parent classes with $this:
<?php
$bar = new Bar();
echo $bar->sayHi(); # will output hello world
It also means we can create a set of generic functions and properties relating to the object to allow more dynamic code. Take these blogs:
title = hello world
content = hello world
img = /path/to/img.jpg
title = what we did last summer
content = played in the park
img = /path/to/another/img.jpg
We can have a blog class like this:
class GenericController
{
# pretend we've done some PDO set up here where we set new PDO to $this->pdo
public function load($id)
{
$sql = 'SELECT * FROM `blogs` WHERE `id` = :id';
$res = $this->pdo->prepare($sql);
$res->execute(array(':id' => $id));
return (object) $res->fetch(PDO::FETCH_ASSOC);
}
}
class Blog extends GenericController
{
protected $id;
protected $data;
public function __construct($id)
{
$this->id = $id;
}
protected function loadData()
{
$this->data = $this->load($this->id);
}
public function getTitle()
{
return $this->data->title;
}
public function getContent()
{
return $this->data->content;
}
public function getImg()
{
return $this->data->img
}
}
$blogOne = new Blog(1);
$blogTwo = new Blog(2);
echo $blogOne->getTitle(); # will output hello world
echo $blogTwo->getTitle(); # will output what we did last summer
further reading:
For MySQL Injection reasons (your code is currently open to said injection):
PDO
PDO Prepared Statements
For OOP:
The Basics
Visibility
And $this from the docs itself (can be found via The Basics link):
The pseudo-variable $this is available when a method is called from within an object context. $this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object). As of PHP 7.0.0 calling a non-static method statically from an incompatible context results in $this being undefined inside the method
$this is a reference of current calling object or we can say that object in use. When you work with multiple instance of class your code base will be manageable for different instances. Also the visibility allows that what you want to keep private or public. And $this will work throughout the object life once you set you can accept anywhere in the object/class scope not limited to the function.

PDO not returning an object, but an array

With the following code, PDO won't return my $parcel as an object, but as an array. There for when i try to call my objects function, it will fail. Every example i have found has done this, in a similar way to mine. What am i doing wrong?
$statement = $this->connection->query($query);
$statement->setFetchMode(PDO::FETCH_CLASS, 'Parcel');
while ($parcel = $statement->fetch()) {
echo $parcel->hello();
}
The Parcel class, if interested.
class Parcel {
public $id;
public $parcel_number;
public $registred_at;
public $shipped_by;
public $shipped_at;
function __construct($parcel_number)
{
$this->parcel_number = $parcel_number;
}
public function hello(){
return "World";
}
}
And im using folder structures to structure the code and an Autoloader, that can probaly affect the PDO's way of calling the object.
While this is the error code
Call to a member function info() on a non-object
This error means the object is null or not instantiated properly, you might need to specify full path to your class.
For example
$statement->setFetchMode(PDO::FETCH_CLASS, 'app\model\Parcel');

Attempt to assign property of non-object error

I am getting this error and i can't see what i am doing wrong. I have done the same thing with other objects from other classes which are built in the exact same way and i can't see why i am getting this error now.
The code in which i create the object is this one:
$consulta2 = "SELECT * FROM TiposDireccion WHERE Cliente_CIF='$cif' and Direccion_Direccion='$direccion' and Direccion_CP=$cp ";
echo($consulta2."</br>");
if ($resultado2 = $conexion->query($consulta2)){
while($fila2 = $resultado2->fetch_object()){
$tipodireccion78=$fila2->TipoDireccion_Tipo;
//we see here that the select is returning a correct string with a correct value
echo($tipodireccion78);
//we try to instantiate and it fails =(
$unTipoDireccion=TipoDireccion::constructor1($tipodireccion78);
This is the class TipoDireccion:
<?php
class TipoDireccion{
private $tipo;
private $descripcion;
//Construct auxiliar
function __construct() {
}
//Constructor 1 : completo
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->tipo = $tipo;
return $tipoDireccion;
}
function ponTipo($tipo) {
$this->tipo = $tipo;
}
function devuelveTipo() {
return $this->tipo;
}
function ponDescripcion($descripcion) {
$this->descripcion = $descripcion;
}
function devuelveDescripcion() {
return $this->descripcion;
}
}
?>
Thank you a lot in advance!
Don't know if this is still relevant to you, but in case anyone else comes on here for an answer. The problem is in this function:
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->tipo = $tipo;
return $tipoDireccion;
}
Because in the class definition, you define private $tipo; and then you try and assign $tipoDireccion->tipo to what was passed through the function. However, you aren't trying to access that variable through the scope of the class, you are trying to assign it from the 'public' scope as far as the class is concerned.
The fix for this has two options, the first one would be to change private $tipo; to public $tipo;. But that isn't a good solution as you have an assignment function for it.
Instead, use your functions that you made, which would make the function look like:
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->ponTipo($tipo);
return $tipoDireccion;
}
That's how you need to access it from the public scope, which you are doing after you initiate a new one.
function constructor1($tipo) {}
should be
static function constructor1($tipo) {}

PHP - Why can't I use private method inside public methods?

Why can't I get access to my "incSessionCount" function inside my "newSession" function?
class Session {
private $_num_session = 0;
private function incSessionCount() {
$this->_num_session++;
}
public static function newSession($key, $value) {
if( !isset( $_SESSION[$key] ) ) {
$_SESSION[$key] = $value;
$this->incSessionCount();
return true;
} else {
return false;
}
}
}
I just played around, like making incSessionCount() public and so on...
And then I thought, that it must be even accessible, when it's set to private ...
It's possible, that I missed a useful article, which should have helped me, but finally I ended up asking.
So why doesn't this work?
The problem is that your newSession is static, thus you are not supposed to call instance methods from it.
I suppose you're trying to do:
Session::newSession($key, $value);
instead of
$session = new Session();
$session->newSession($key, $value);
The error is not because you're calling a private method from within a public one, but because you're using $this instead of self.
$this special variable represents the current instance object while self represents the class itself.
If you enable error display and set error reporting level to E_ALL, you will see the problem is about using $this in a wrong context.
See below theses little modifications to do what you want, and check theses pages about
class Session {
private $_num_session = 0;
private static $inst = null;
public static function instance(){
if (!static::$inst)
static::$inst = new Session();
return static::$inst;
}
private function incSessionCount() {
$this->_num_session++;
}
public static function newSession($key, $value) {
if( !isset( $_SESSION[$key] ) ) {
$_SESSION[$key] = $value;
Session::getInstance()->incSessionCount();
return true;
} else {
return false;
}
}
}
You can look for design pattern and singleton on internet, and use magic __clone() to forbid more than one instance
I only found the german version of the documentation, I don't know why : http://de.php.net/manual/de/language.oop5.patterns.php
EDIT: Check this link about design patterns : http://www.phptherightway.com/pages/Design-Patterns.html
Remember, that static methods are binded with the class. Non-static methods are binded with the instance (when you do something like $instance = new MyClass();). But when you call something on the static context, you don't have to have any instance.
It's the same, when you want to call something on instance($this), because in static context doesn't exist any instance.
The problem is the public method is static and you are trying to use a method for an instantiated object. In a static method the $this variable refers to other static methods and properties only.

PDO Class scope call to undefined method

I'm trying to create a simple class based on my database PDO class that I can say "get this id" and it will print the info. I'm trying to do this in "qu" but get the following error: "Call to undefined method qu::get()".
There's probably a mixture of problems so any help here would be awesome. Thanks a lot!!
class db {
protected static $conn;
private function __construct(){}
public static function connect() {
if (!isset(self::$conn)) {
self::$conn = new PDO('mysql:host=localhost;dbname=database', DB_USER, DB_PASSWORD);
}
return self::$conn;
}
}
class qu {
private $db;
function quconn (&$db){
$this->db = &$db;
}
private static function getq($id){
$sql="SELECT * FROM table WHERE id=:id";
$stmt = self::quconn()->prepare($sql);
$stmt->execute(array(':id'=> $id));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
}
//$data = db::connect()->query("SELECT * FROM table")->fetchAll(); // this works
$data = qu::getq("22"); //can i use something like this? this causes the error
print_r($data);
function getq of class qu should be marked with public access modifier.
Otherwise the following row will fail as getq is a private function
$data = qu::getq("22");
Second and issue in this code
function quconn (&$db){
$this->db = &$db;
}
As you enter function quconn from a static content $this is unavailable.
Use self::$db instead.
For class qu follow the same structure of class db wich is a singleton mnagament class.
I also suggest to clarify yourself differences between $this and self, static contest etc..
Php offiacial documentation offers al lot about
Also i don't think you need passing-by-reference method:
try to rewrite the quconn function as follows:
function quconn ($db){
self::$db = $db;
}
By the way i don't thing the class qu is well "engineered"
Even if you correct the passing-by-reference-problem this instruction won't work:
$stmt = self::quconn()->prepare($sql);
You are invoking the prepare function on the result of the invocation to quconn, which doesn't return anything...
I suggest:
$stmt = db::connect()->prepare($sql);
this get the PDP instance and call the prapare method....

Categories