If I create a class that uses a variable defined in another php file that is included via require_once, I get the following outcomes:
If require_once is at the top of the class's php file and the variable is used in myclass->someFunction() it will throw the error: Undefined variable
If require_once is inside myclass->someFunction() it work once and thereafter throw the error: Undefined variable
How do I properly handle this?
Example showing the problem:
test.php
<?php
require_once( "holds_var.php" );
class T
{
function __construct()
{
$this->useVariable();
}
function useVariable()
{
echo $something;
}
}
$t = new T();
?>
holds_var.php
<?php $something = "I am something"; ?>
EXAMPLE 2 (uses the same "holds_var.php" ):
test.php
<?php
class T
{
function __construct()
{
//This is ok
$this->useVariable();
//This throws an error
$this->useVariable();
}
function useVariable()
{
require_once( "holds_var.php" );
echo $something;
}
}
$t = new T();
?>
Use global keyword:
function useVariable()
{
global $something;
require_once( "holds_var.php" );
echo $something;
}
Sounds like global could help your case.
http://us3.php.net/manual/en/language.variables.scope.php
holds_var.php
<?php
$something = "I am something";
global $something;
?>
test.php
<?php
require_once( "holds_var.php" );
class T
{
function __construct()
{
//This is ok
$this->useVariable();
//This throws an error
$this->useVariable();
}
function useVariable()
{
global $something;
echo $something;
}
}
$t = new T();
?>
How does the above code work out for you?
Related
Consider the following. I have 4 files.
sub.php
<?php
class sub extends main {
function __construct() {
parent::__construct();
echo "constructor in sub<br>";
}
}
trait.php
<?php
trait t1 {
function tProcess() {
echo "in tprocess in trait<br>";
}
}
main1.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
require_once 'sub.php';
require_once 'trait.php';
class main {
function __construct() {
echo "constructor in main<br>";
}
function process() {
echo "doing something in main<br>";
}
}
$t = new sub();
$t->process();
and main2.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
require_once 'sub.php';
require_once 'trait.php';
class main {
use t1;
function __construct() {
echo "constructor in main<br>";
}
function process() {
echo "doing something in main<br>";
}
}
$t = new sub();
$t->process();
main1 works as expected, but main2 gives me a Fatal error: Class 'main' not found error. Just including the trait is changing something in the behavior of how the file inclusions work.
Yup, it is just an include ordering issue. This is one of the countless reasons people use the autoloader.
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
require_once 'trait.php';
class main {
use t1;
function __construct() {
echo "constructor in main<br>";
}
function process() {
echo "doing something in main<br>";
}
}
require_once 'sub.php';
$t = new sub();
$t->process();
I have coded my own PHP auto class loader but I receive the following error when I try to use the class functions with the class
Fatal error: Call to a member function Test() on a non-object
I would also like to know if this approach is the best approach available and if anyone suggests a better way of coding this then I will appreciate it.
$class = array();
foreach (scandir(include_dir) as $filename)
{
if (is_file(include_dir . '/' . $filename))
{
//its a php file, lets do this!
if (substr($filename, -4) == '.php')
{
$page = preg_replace('/\.php$/','',$filename);
$class[$page] = GetClass($page);
}
}
}
$class['Blue']->Test2();
$class['Blue2']->Test();
Iat seems that this error only occurs when there is numbers in the filename / class
And here is class loader file that i include in my index the class Blue works but Blue2 doesn't and throws that error.
function GetClass($class)
{
if (CheckAllOkay($class))
{
include('/blue/' . $class . '.php');
if (ClassCanBeAutoLoaded($class))
{
$newclass = new $class;
return $newclass;
}
}
}
function ClassCanBeAutoLoaded($class)
{
return class_exists($class);
}
function CheckAllOkay($class)
{
return file_exists($class);
}
Here is the class Blue2
<?php
class Blue2
{
function __construct()
{
echo '[LOADED]';
}
public function Test()
{
echo '[TEST CALLED]';
}
}
?>
Class Blue is the same is just echos a diffrent text and has a diffrent class name
I have this code:
//config.php
$EXAMPLE['try1'] = "...." ;
$EXAMPLE['try2'] = "...." ;
So, i have another file with a php class:
class try {
public function __construct() {
if($this->try1() && $this->try2()){
return true;
}
}
public function try1(){
require_once 'config.php' ;
echo $EXAMPLE['try1'];
return true;
}
public function try2(){
require_once 'config.php' ;
echo $EXAMPLE['try2'];
return true;
}
}
But in my case, $EXAMPLE['try1'] is ..... , but $EXAMPLE['try2'] is null... why? I've tried to include require_once 'config.php' ; on top page, and add after global $EXAMPLE; , but $EXAMPLE is ever null, why?
Use require, not require_once. Otherwise, if you load the file in one function, it won't be loaded in the other function, so it won't get the variables.
It would be better to require the function outside the functions entirely. Then declare $EXAMPLE as a global variable.
require_once 'config.php';
class try {
public function __construct() {
if($this->try1() && $this->try2()){
return true;
}
}
public function try1(){
global $EXAMPLE
echo $EXAMPLE['try1'];
return true;
}
public function try2(){
global $EXAMPLE
echo $EXAMPLE['try2'];
return true;
}
}
Require your file inside __construct method. So require once requires file once in try1 method.
class try {
private $_example = array();
public function __construct() {
require_once 'config.php';
$this->_example = $EXAMPLE;
return $this->try1() && $this->try2();
}
public function try1(){
echo $this->_example['try1'];
return true;
}
public function try2(){
echo $this->_example['try2'];
return true;
}
}
Trying to get a hang of classes in php, trying to include carClass.php into new_file.php.
carClass.php
<?php
class carClass
{
private $color;
private $gear;
private $model;
private $gas;
function paintCar($carColor) {
$this->color = $carColor;
}
function findCarColor() {
echo "$color";
}
function shiftGear($newGear) {
$this->gear=$newGear;
}
function findGear() {
echo "$gear";
}
function chooseModel($newModel) {
$this->model = $newModel;
}
function findModel() {
echo"$model";
}
function fillCar($gasAmount) {
$this->gas = $gasAmount;
}
function lookAtGauge() {
echo "$gas";
}
}
?>
its just a bunch of getters and setters. Im trying to include this class to new_file.php
new_file.php
<?php
include("carClass.php");
$car = new carClass;
$car->chooseModel("Mustang");
$car->paintCar("black");
$car->shiftGear("5th");
$car->fillCar("half");
$car->findModel();
$car->findCarColor();
$car->findGear();
$car->lookAtGuage();
?>
When I try to execute this file I get these error messages
Warning: include(carClass.php): failed to open stream: No such file or directory in C:\xampp\htdocs\testFile\new_file.php on line 4
Warning: include(): Failed opening 'carClass.php' for inclusion (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\testFile\new_file.php on line 4
Fatal error: Class 'carClass' not found in C:\xampp\htdocs\testFile\new_file.php on line 6
I believe both files are in testFile directory so I'm not sure whats going on. I appreciate any help you guys can give me as usual.
The include path is set against the server configuration (PHP.ini) but the include path you specify is relative to that path so in your case the include path is (actual path in windows):
<?php
include_once dirname(__FILE__) . '/carClass.php';
$car = new carClass;
$car->chooseModel("Mustang");
$car->paintCar("black");
$car->shiftGear("5th");
$car->fillCar("half");
$car->findModel();
$car->findCarColor();
$car->findGear();
$car->lookAtGuage();
?>
You can use PHP's auto loading feature which will automatically load a class when an object is created. If you have many classes then you can use it an header file so that you don't need to worry about using this include every time.
<?php
function __autoload($class_name) {
include $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
Try this:
<?php
class carClass
{
private $color;
private $gear;
private $model;
private $gas;
function paintCar($carColor) {
$this->color = $carColor;
}
function findCarColor() {
echo $this->color;
}
function shiftGear($newGear) {
$this->gear=$newGear;
}
function findGear() {
echo $this->gear;
}
function chooseModel($newModel) {
$this->model = $newModel;
}
function findModel() {
echo $this->model;
}
function fillCar($gasAmount) {
$this->gas = $gasAmount;
}
function lookAtGauge() {
echo $this->gas;
}
}
?>
//
<?php
include("carClass.php");
$car = new carClass;
$car->chooseModel("Mustang");
$car->paintCar("black");
$car->shiftGear("5th");
$car->fillCar("half");
$car->findModel();
$car->findCarColor();
$car->findGear();
$car->lookAtGauge();
?>
I am writing a config file parser and have a function called getVals() in my Config.php file but apparently when I call it in a test it throws an "Undefined function" error.
Config.php
<?php
require_once '../extlib/pear/Config/Lite.php';
class Config {
private $config;
function __construct($conf) {
$this->config = new Config_Lite();
echo "calling open...<br>";
$this->open($conf);
echo "open done...<br>";
}
function open($cfile) {
if (file_exists($cfile)) {
$this->config->read($cfile);
} else {
file_put_contents($cfile, "");
$this->open($cfile);
}
}
function getVals() {
return $this->config;
}
function setVals($group, $key, $value) {
$this->config->set($group, $key, $value);
}
function save() {
$this->config->save();
}
}
?>
Testing class in cfgtest.php
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
require_once '../util/Config.php';
$cfile = "../../test.cfg";
$cfg = new Config($cfile);
if (is_null($cfg)) {
echo "NULL";
} else {
echo $cfg.getVals();
}
?>
Output
calling open...
open done...
Fatal error: Call to undefined function getVals() in cfgtest.php on line 13
I would like to know why the undefined function error appears when there's the function there already.
In php to call a method or a member of an object, use the -> operator:
if (is_null($cfg))
{
echo "NULL";
}
else
{
echo $cfg->getVals();
}
Learn more on PHP Object Oriented Programming on PHP's website.
Call should be using -> operator
$cfg.getVals();
should be
$cfg->getVals();
Use $cfg->getVals(); instead of $cfg.getVals();
Now you are trying to do a concatenation !
Ooops ... missed the '->'. Lol. Good catch for all.