I have a header method that shows in the top of a page, it is inside a class, inside my header() method I run this code here to start a new Profiler object...
//start new page timer object
$profiler = new Profiler;
$profiler->start();
After a bunch of other files are compiled, I then include a file into the footer section, in this file I run this code,
echo 'Page Generated in ' .$profiler->end(). ' of a second with ' .$_SESSION['querie_counter']. ' MySQL Queries';
However I am getting this error message in the footer file now,
Notice: Undefined variable: profiler
in
C:\webserver\htdocs\friendproject2\includes\footer.inc.php
on line 21
Fatal error: Call to a member function
end() on a non-object in
C:\webserver\htdocs\friendproject2\includes\footer.inc.php
on line 21
How can I fix this?
If you created the $profiler object inside the header method, it will not be available in another method, unless it was a global $profiler was a global variable or it was a singleton.
To make it global, declare $profiler outside the header method and then inside the header method, include this line:
global $profiler;
Include this line in the the footer method as well. The rest of your code can stay the way it is. It should work.
Variables created in a function are local to that function. Use the global keyword to declare a global variable.
I'd suggest make the $profiler a property of the main class and initialize it inside the constructor method, since it's not really related to the header.
Assuming this is the main class
class Example {
private $profiler;
public function __construct() {
$this->profiler = new Profiler;
}
public function header() {
...
}
}
Inside the included header, initialize this object and run header, and just to make it more explicit, make the profiler start call separately:
$example = new Example();
$example->profiler->start();
$example->header();
Inside the included footer:
$example->profiler->end();
Possible Steps:
First of all make sure that you include the file which contains the profiler class.
If you are using the profiler instance inside a function, you need to use the global keyword:
global $profiler;
I Think if you remove session() from the top of your header your problems will be fixed ...
Related
I was wondering if you can explain why PHP acts this way when including files in __construct methods.
class sitePosting{
private $conx;
public function __construct() {
include_once("".$_SERVER['DOCUMENT_ROOT']."/auth/db_conx.php");
$this->conx = $conx;
}
It seems that if I call another class which has this file included in its __construct, I get an undefined variable error when trying to use $conx in the first class, but from what I understand isn't __construct run when the object is first built?
What's weirder, if I change...
include_once("".$_SERVER['DOCUMENT_ROOT']."/auth/db_conx.php");
TO
include("".$_SERVER['DOCUMENT_ROOT']."/auth/db_conx.php");
This fixes the problem entirely, but I have no idea why
Any insight into why this occurs is appreciated.
Thanks,
Just as the names says: include_once includes the file only once. If You have included it earlier it won't be included again. Also, classes and functions don't see the global scoped variables unlike JavaScript for example. That's why the $conx variable is unreachable from within You sitePosting class.
It would be better if You placed $conx as class argument like this:
public function __construct($conx) {
$this->conx = $conx;
}
It's called Dependency Injection and is definitely a good practice to use. Makes Your code much cleaner and understendable.
Trying to get a simple template system working, but it seems to affect another class.
I have two PHP classes, both called in index.php:
HeaderData.php - class allows user to setup Header data, eg doctype,
charset.
PageTemplates.php - class allows user to include a template file.
When I call the HeaderData class, then manually require() a template file from view (ie contains doctype, head, meta tags etc), the code from the header class works fine in the template file, outputting the objects from the header class such as Doctype etc.
However, when I try to use the PagesTemplate class to include the template file (with manual require() removed from index.php), the template file is included, but the HeaderData class no longer works in it.
Error log shows:
Notice: "Undefined variable varHeaderData";
Error: "Call to a member function PageDoctype() on a non-object";
Both the variable and function worked fine when manually require() the template file in index.php.
The code below is dev only (data checks etc to be added):
index.php:
// Use HeaderData Class
$varHeaderData = new HeaderData(
array(
'PageDoctype' => '<!DOCTYPE html>',
'PageCharset' => 'UTF-8',
));
// Use PageTemplates Class
$varPageTemplate = new PageTemplates();
$varPageTemplate->LoadTemplate('template-file.php');
PageTemplates.php Class:
class PageTemplates
{
private $strTemplatesDir = 'view/templates/';
public function __construct($strTemplatesDir = NULL)
{
if ( is_dir($strTemplatesDir) )
{
$this->strTemplatesDir = $strTemplatesDir;
}
}
public function LoadTemplate($strTemplateFile)
{
{
require_once ($this->strTemplatesDir.$strTemplateFile);
}
}
}
template-file.php:
echo $varHeaderData->PageDoctype();
The HeaderData class simply sets the object the user entered in the array with the PageDoctype() function in the class (again this works fine without the page template class)
Can someone tell me why when using the template class to require() the template file, it stops the objects from the HeaderData from working in the template-file.php?
The simplest way to do it is to pass variable in to the LoadTemplate method as an array and use extract function:
public function LoadTemplate($strTemplateFile, $vars = array())
{
extract($vars);
require($this->strTemplatesDir.$strTemplateFile);
}
And in the index.php
...
$varPageTemplate->LoadTemplate('template-file.php', array(
'varHeaderData' => $varHeaderData
));
One of your errors says: "Call to a member function PageDoctype() on a non-object", so make sure that PageDoctype() method is defined in the HeaderData class.
I'm coding a Wordpress plugin and I'm not sure regarding the function name conflict..
I have a file named test_handling.php which contains the following content :
function testing() { echo 'test'; }
I included this file in a class constructor (file named testcls.class.php) :
class TestCls {
function __construct() {
require_once('test_handling.php');
testing();
}
function otherfunction() {
testing();
}
// ...
}
In this case, I would like to know if the testing() function is only available in the TestCls class, or can it create conflicts if an other WP plugin has a function with the same name ?
Even with the same name, the functions will have different scope if defined as class method. To make a call to a regular function you will do the following:
testing();
and the result will be:
'test'
the class method need an instance of the class or be statically called. To call the method class you will need the following formats:
$class->test();
or
OtherPlugin::test();
To sum up, the function test will be different if defined as class method. Then, you will not have conflicts.
Other way to encapsulate your function and make sure you are using the right one is with namespaces. If you use a namespace in your test_handling.php
<?php
namespace myname;
function testing(){echo 'test';}
?>
You will access the function test like this:
<?php
require_once "test_handling.php";
use myname;
echo myname\testing();
Now you are sure about the function you are calling.
When a file is included, the code it contains inherits the variable
scope of the line on which the include occurs. Any variables available
at that line in the calling file will be available within the called
file, from that point forward. However, all functions and classes
defined in the included file have the global scope.
from include in PHP manual
Which means that yes, you can have conflicts.
i have included a file in another file and now i want to use on of the functions from the included file.
when i go to the included file and put a variable there the variable get passed and its all good
- that means i have includedd the right file.
but when i want to call a funcion which is inside a class
class SimpleViewer {
.
.
.
.
function whatever(){}
it just doesnt call it when i each it and writes
Fatal error: Call to undefined function display_gallery_table()...
i know for sure im in the right file because the other values passed but i just can call nothing because its insidfe the class
what am i doing wrong?
Try initiating an instance of the class first like this
$myClass = new SimpleViewer();
then call the function like this
$myClass->whatever();
$var = new SimpleViewer();
$var->whatever();
You need to create an instance of the object first;
$obj = new Class();
$obj->func();
There are many ways to call a function between classes. The first I know is a static method call. You can call function by defining class::function().
example :
public class Parent{
public static function check(){
....
....
}
}
the static caller may look alike
Parent::check()
Second way is initiate the class as the new object. From the example we can do the call like
$obj = new Parent;
$obj->check();
the rest manual of implementing this is on php manual
Please review the example code below, I have a class file that is loaded into a config file. The config file is then loaded into any page I build. Is it possible to include a header file the way I have in the show_header() method? It doesn't seem to work so how can I achieve this result?
// Core.class.php
class Core
{
public function show_header($page_name){
require_once 'includes/header.inc.php';
}
}
// config.inc.php
require_once 'Core.class.php';
$core = New core;
// testpage.php
require_once 'config.inc.php';
$core->show_header('home');
Here is the top part of the header.inc.php file I am trying to include into the page, it seems to work including it but it breaks the way the header file works.
//header.inc.php
<?PHP
//start page timer
$session->get('user_id');
$profiler = new Profiler;
$profiler->start();
//see if site is turned on/off
$core->sitestatus($config['site_status']);
This part gives me errors like this...
Notice: Undefined variable: session in
C:\webserver\htdocs\friendproject2\includes\header.inc.php
on line 5
Fatal error: Call to a member function
get() on a non-object in
C:\webserver\htdocs\friendproject2\includes\header.inc.php
on line 5
When you're including a file from within a function it's just as if you wrote the code within that file from within that function.
e.g.
file foo.php:
<?php
echo $foo->getFoo();
file bar.php
<?php
class Foo {
public function getFoo() {return 'foo';}
}
$foo = new Foo();
function bar()
{
require 'foo.php';
}
bar();
The above will result in the following notice/error being thrown, because $foo is not known within bar().
Fatal error: Call to a member function getFoo() on a non-object in /Users/hobodave/foo.php on line 3
Edit:
I'm not sure what your "Core" class fully entails, but you could perhaps use it as a type of storage for your "globals".
e.g.
<?php
$session = new Session();
$core->session = $session;
Then your $session would be accessible in your header using $this->session
re your comment, sounds like you need a root web context object that you reference the other objects from:
$ctx = WebContext::get();
$ctx->session->get('x');
$ctx->input->get('y');
$ctx->identity->valid;
etc... this is how most web frameworks do it.
$session would need to be defined, then referenced in the included file:
// If a global variable:
global $session;
$session->get('x');
// If a member of Core:
$this->session->get('x');
yes you can do that, probably you'll want require instead of require_once, and the paths would need to be based on the current working directory or an absolute path
try adding error_reporting(E_ALL) to see if any notices are happening...
All calls you make inside the header file will be called as if they were local calls inside the show_header function. So if you want to use any global variable, you will have to use global $variablename; on the top of the included file (or in the beginning of the show_header function).
If you use a static function for the session class you wouldn't need to define it in the same file. http://php.net/manual/en/language.oop5.static.php
You are trying to access $session which is out of scope as pointed in another answer.
Since session stuff is usually global throughout most apps consider using the singleton pattern for the Session class.
This way you can do something like $session = Session::getInstance().
This lets you use the session class anywhere and you usually only one need one instance of a session class (usually). Take a look at Zend Framework for examples on singleton classes.