Using a function from another class - php

I'm just starting with OOP (shame on me), so be gentle with me.
I have an ErrorHandler class that calls a function from my main Application class to include an error page.
So I'm using Application::status_page( $type ); in a function in the ErrorHandler class.
This is how the status_page function looks like (it's a function to include all kinds of custom messages):
public function status_page( $page )
{
// Include the status page that has been set in the routes
include( STATUS_PAGE_DIR . $this->status_pages[$page] . '.html' );
}
I'm now getting an Undefined property: ErrorHandler::$status_pages which makes total sence to me. But what is the best way to solve this? Maybe let the ErrorHandler class extend the main Application class?
I hope I was clear and thanks in advance for answering.

$status_pages must be defined in the header of the class
also, you must declare the function as
public static function status_page($page)
if you want to use it like that.

Related

PHP MVC Call Model in another Model

Sorry if the question has already been asked, but I have wanted to know if import a model in another model MVC is correct or whether it is best to do the same function in EVERY models?
For now in the Model in my Library folder I add the same method as in my Controller:
class Model
{
protected function __construct()
{
$this->db = new Database;
}
public function model($model)
{
require_once '../app/models/' . $model . '.php';
return new $model();
}
}
And in my model file :
class Exemple_model extends Model
{
function __construct ()
{
parent::__construct();
}
public function exemple_function()
{
$otherModel = $this->model('urlAnotherModelFile');
$otherModel->otherMethod();
}
}
But I am not sure it is correct to do so or if is the best way.
Thank you in advance for your answers.
You are kind of mixing things up I think.
Your controller is responsible for creating models, and executing methods on them. You can rename you Model class to BaseModel, and make each model extend from this BaseModel.
As for the problem of including the right files, I would recommend you take a look at the autoloader: http://php.net/manual/de/function.spl-autoload-register.php. This may look a bit confusing at first, but if look at the first example you will quickly understand what is the gist of it: basically if you want to create a object of a specific class, php checks if it already knows that class, and if not, it will execute the autoloader (which then tries to include the file containing the class). As soon as you have configured the autoloader, you can stop caring about including the right files.
As autoloader might be a bit confusing at first, this would be the autoloader in your specific use case:
spl_autoload_register(function ($model) {
include '../app/models/' . $model. '.php';
});
You need to put this snippet somewhere before you construct / access a model. Everything else is done by php (it calls automatically the function as it needs to, so calling something like spl_autoload_register('Comments_model::comments_list'); would not work at all :)
Now if you want to execute a method from a model, you can do this as following:
$otherModel = new otherModel();
$otherModel->otherMethod();
no worries about require or similar, php does this for you.

Can't use library functions inside a controller

I am trying to create my own library so i can handle custom areas in my application. i have a small library located at application/libraries which i called randomizer. it looks like this:
Class Randomizer {
public function __construct()
{
parent::_construct();
$CI =& get_instance();
$CI->load->library('session');
$CI->load->database();
}
function test_function($name)
{
return 'Hi dear' . $name . 'welcome back!';
}
}
In my Controller i tried to test out the simple test_function:
public function index()
{
echo($this->Randomizer->test_function('John'));
exit;
}
And I am getting the following error
Call to a member function test_function() on a non-object
There are couple of possible errors i can see. first you are not loading the library you created inside your controller. in case you don't use $this->load->library('randomizer'); right before you call the library funcion. if you are going to use the library all over the controller then load it via the controller __consturct. Also i guess you are not extending an existing Class so the parent::_construct() is not needed. make sure you understand why you are using a library and when you should use helpers. Read more about Codeigniter Libraries
Please look closely to the documentation. There are a few problems.
First of all it seems that you have either not loaded the library ($this->load->library('randomizer')), otherwise you would get a syntax error because your are calling parent::_construct(), instead of parent::__construct. And you do not have to call that function anyway, because your class doesn't have a parent (it doesn't extend a class...).
Furthermore, although you declare your class with a capital, the variable will be lowercase. So you should call $this->randomizer->test_function()

Init another class in construct method?

I am looking into trying to simplify my PHP code some more, and I have yet to find an answer with this methodology one of my team members are using. Nor, have I ever saw this done before anywhere on the web.
Here is the code example from our web application which he is working on with me.
<?php
class ArticlesHandler {
public function __construct() {
require 'Articles.php';
$articles = new Articles;
}
}
?>
Is this proper to init one class within another class?
For me, this just seems not proper standard to init classes to work together.
Yes and no. It works, but this particular code can lead to a number of problems.
You should be using require_once instead of require to avoid possible errors of including the same file twice. As it is this code here will bring your app to a complete stop:
new ArticlesHandler;
new ArticlesHandler;
This creates a hard coupling to the Articles class. You should probably rather be using dependency injection and pass an instance of Article to the constructor of ArticlesHandler. See How Not To Kill Your Testability Using Statics.
Yes, it is proper and normal to call constructors in a constructor. There is nothing weird/bad about it.
This is what I normally do.
class Repository {
protected $_models = array();
public function getModel($model, array $params = array()){
require_once $model.'.php'; //Replace this with an autoloader
if(empty($this->_models[$model])){
if(!empty($params)){
$this->_models[$model] = new $model($params);
} else {
$this->_models[$model] = new $model();
}
}
return $this->_models[$model];
}
}
And call the other class like this.
class ArticlesHandler extends Repository {
public function __construct() {
$articles = $this->getModel('Articles');
}
}
it seem's right.
For me, this just seems not proper standard to init classes to work together.
you can extend Articles class if you want to use Articles class inside the ArticlesHandler

function in codeIgniter help conflicting with another function

In codeIgniter I auto load the url_helper.php
In my site I also have a phpbb forum and so within codeigniter im trying to include a script from the forum.
The problem is, phpbb tries to declare a function redirect() but its already declared in the url_helper.php so i get the following error
Cannot redeclare redirect() (previously declared in
C:\Apache24\htdocs\system\helpers\url_helper.php:531) in
C:\Apache24\htdocs\forum\includes\functions.php on line
2562
What can I do go go around this? Can I unset the function or remove the url_helper entirly in my controller function?
Still a bit of a hack, but see: http://php.net/manual/en/function.rename-function.php
You could create your own url_helper, include the CI url_helper, and call after include:
rename_function('redirect', 'ci_redirect');
Ok, I got a work around. In the codeigniter's helper library, before declaring a function, it first checks if it has been declared before or not. So....
In my controller class's constructor method, I load all the phpbb files I need. this way it declares the phpbb redirection function and codeigniter goes "ohh there is already a redirect function" and so it doesn't declare the redirect function... Problem solved
Something like this:
class Register extends CI_Controller{
public function __construct()
{
/* START phpbb */
.
.
.
require_once('forum/common.php');
require_once('forum/includes/functions_user.php');
require_once('forum/includes/functions_module.php');
/* END phpbb */
//Continue as normal
parent::__construct();
}
public function index(){
//Your stuff works as normal now
}
}

is there any way to get the information of classname and filename regarding a function in PHP OOPS

i m learning OOPS with JOOMLA... here sometimes i found difficulties to find the method used in some class...
is there any way to find that this function is declared on this class or useful information about that function??
for exmaple
class testModeltest extends JModel
{
function modifyCategory($data = array())
{
$image = $this->imageResize($value);
.......
}
}
now i want to know where the imageResize() function declared/defined first time...means class and file name where this function born
i used magic constact __METHOD__ this retrive useful information inside class . i need such type of function where i just put method name & i get the complete information of that function
i want a below kind of facility( i m sure there are some function in php to get the information about class but don't know )
functionInfo($methodname) // here i just put the function name
which return
Function Name:imageResize
Main class : imageclass
File name where it has been declared : /foldername/filename.php
currenty using(called) in : thisclass::this function
If you are looking for the place where a method was first defined, that should be possible using get_parent_class() - here is a snippet that walks through each class definition - and doing a method_exists() on each class found that way.
However, this will not show where the method has been subsequently overriden, so it may be of limited use to you - in that case, something like Reflection is probably indeed the only way.

Categories