I am developing a project using fat free PHP framework. In the documentation, they said you can build your own skeleton for the project, so my project directory is like the following:
in the index.php I am calling the framework (controllers and models including the database connection) and having my routes as the following:
// Kickstart the framework
$f3=require($_SERVER['DOCUMENT_ROOT'] . '/project_name/lib/base.php');
$f3->set('AUTOLOAD',''.$_SERVER['DOCUMENT_ROOT'] . '/project_name/controllers/; '.$_SERVER['DOCUMENT_ROOT'] . '/project_name/models/');
$f3->set('DEBUG',3);
if ((float)PCRE_VERSION<7.9){
trigger_error('PCRE version is out of date');
}
if (!($f3->get('DEBUG')))
{
$f3->set('ONERROR',
function($f3) {
$f3->reroute('/');
}
);
}
/****************** Start Routing the URLs ******************/
/****** Home Controller ******/
$f3->route('GET|HEAD /',
function($f3) {
$f3->reroute('/home');
}
);
$f3->route('GET|HEAD /index',
function($f3) {
$f3->reroute('/home');
}
);
$f3->route('GET /home','Controller_Home->main');
$f3->run();
inside Model.php I have a function that connect successfully to the database that I have like the following:
class Model
{
public $f3, $db;
public function connect()
{
global $db;
$username = 'username';
$password = 'password';
$hostname = 'hostname';
$dbname = 'dbname';
try{
$db = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
echo $e->getMessage();
}
print_r($db); // this will give PDO Object ( )
$this->db = $db;
}
}
// if you try to execute query here, it will work.
Now, in Controller.php I am calling the connect() function in Model.php inside the construct like the following:
class Controller extends Model
{
public $f3, $db;
public function __construct($f3)
{
$this->f3 = $f3;
$this->connect();
}
}
Model_Home.php has functions that queries the database like the following:
class Model_Home extends Model
{
public $f3, $db;
public static function getUsers()
{
$query = "SELECT * FROM users";
$result = $this->db->query($query);
$output = '';
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$output.= '<tr>
<td>'.$row['attrib1'].'</td>
<td>'.$row['attrib2'].'</td>
<td>'.$row['attrib3'].'</td>
<td>'.$row['attrib4'].'</td>
<td>'.$row['attrib5'].'</td>
</tr>';
}
return $output;
}
}
and Controller_Home.php will call the previous function statically and then call the right view to render the result like the following:
class Controller_Home extends Controller
{
public $f3, $db;
public function main($output = '')
{
//setting up the variables
$this->f3->set('getUsersTable', Model_Home::getUsers());
// getUsersTable is a variable that will be passed to the view to reder
//calling the view
$this->f3->set('main','views/home/main.html');
}
}
The last thing is the main.html page which is like the following:
<h1>All Users</h1></br>
<?php echo htmlspecialchars_decode($getUsersTable); ?>
when I run the code, it will give me an error message says: Fatal error: Using $this when not in object context
project_name/models/Model_Home.php:8
which refers to the following line in Model_Home.php
$result = $this->db->query($query);
the php version that I have to use is 5.4 (pretty old). Any idea, please!
Thanks everyone!
You have defined Model_Home::getUsers as a static method. This means it is a method of the class and not the instantiated object, which in turn means you don't get access to object properties, only class properties and methods defined as "static" . $db is not defined as "static" and therefore it's a property of the object and not the class.
If you want to keep getUsers as static:
You can either define $db as "static" (which will require other code changes for any code that references it), or use the Singleton pattern whereby an instance of an object is stored as a static class variable for access by other class methods. Eg:
class myClass
{
protected static $db = null;
public static function getDb()
{
if(empty(self::$db))
self::$db = new Database();
return self::$db;
}
}
If you don't care about keeping getUsers static:
Just remove the "static" keyword from its declaration, and you will also have to update this method call from:
$this->f3->set('getUsersTable', Model_Home::getUsers());
to:
$modelHome = new Model_Home;
$this->f3->set('getUsersTable', $modelHome->getUsers());