I have a class named CMS which relies on a file names "DB.json"
I am using the following code:
class CMS{
function __construct(){
$DB = json_decode(file_get_contents("DB.json"));
}
}
which works fine as long as the file I am requiring the class from is inside the same directory
so if "/classes/cms/lib.php" is my class file and require "lib.php" inside the file "/classes/cms/form.php" then it will work
but if I require "/classes/cms/lib.php" from inside of a file such as "/home.php" then I get an error message saying that the file "DB.json" doesn't exist
link: http://www.streamlinedesign.ml/testcms.php
Use magic constant __DIR__ - it will indicate the directory of the current file (from which the constant is accessed):
class CMS{
function __construct(){
$DB = json_decode(file_get_contents(__DIR__.DIRECTORY_SEPARATOR."DB.json"));
}
}
Related
I have a a class stored in path plug/PHPDocumentParser/DocumentParser.php:
namespace LukeMadhanga;
class DocumentParser {
static function parseFromString($string) {
// do stuff
}
}
I want to call the class and function. I run this in a file that's stored at the base folder:
include_once("plug/PHPDocumentParser/DocumentParser.php");
$docObj = new DocumentParser();
$docText = $docObj->parseFromString('hello world');
I receive this error:
Fatal error: Class 'DocumentParser' not found
I am pretty sure the problem is how I call the class, correct?
You are calling static function in wrong way. Try
DocumentParser::parseFromString()
Also use require_once, you will know if it was included correctly. (maybe path is wrong.)
Edit : Ok, you added namespace now - it should be \LukeMadhanga\DocumentParser::parseFromString() thats also why you dont get instance of DocumentParser using new.
Of course you can always add use keyword at top of your file to include your namespace.
I'm trying to autoload Classes, but I'm hindered by the scope. The Class is being loaded, but I'm using it out of scope. Here's the code to further explain what I'm trying to do.
AutoLoader.php
<?php
class AutoLoader {
private $namespace;
public function __construct($namespace) {
$this->namespace = $namespace;
spl_autoload_register(array($this, 'ClassLoader'));
}
private function ClassLoader($class) {
$class = "classes/{$this->namespace}/{$class}.php";
print("Loading class: {$class}");
include "{$class}";
}
}
?>
script.php
<?php
ini_set("display_errors", 1);
$loader = new AutoLoader("myspace");
$MyClassObj = new MyClass();
$result = $MyClassObj->MyClassFun();
?>
So when it comes down to script.php, I get the print out that it's loading the class and I don't get any errors that it can't find the file. So it looks like it's loading, but when I use the class to create a new object, it tells me it can't find the class. So I'm loading the include out of scope.
I included the AutoLoader in a separate file so I could load it into multiple files. Am I able to make this work or must the AutoLoader be part of script.php instead of separate?
edit: Including error, added error display to script.php.
Loading class: classes/myspace/MyClass.php
Fatal error: Class 'MyClass' not found in /usr/local/apache2/htdocs/scripts/script.php on line 5
edit: Including MyClass.php and directory structure
MyClass.php
<?php
class MyClass {
public function MyClassFun() {
$var = "hello world";
return $var;
}
}
?>
Directory Structure
htdocs/scripts/script.php
htdocs/classes/myspace/MyClass.php
htdocs/AutoLoader.php
If I change the class to MyClasse (misspelled) it will error on the include because it can't find the file. So using the proper MyClass I can only assume that it's finding the file since it's not producing an error. So the include looks good, but it still won't use it.
Which, now that I think about it more, is strange. The include is only occuring because of line 5 when I go to use the class. ClassLoader is being called by the spl_auto_register to search for the class. It's finding and including the class. Yet the same line 5 fails to actually use it.
I guess I don't understand that disconnect. Line 5 is properly calling the ClassLoader, but then fails to actually find the class once loaded.
I have a problem while including my own php class page from its server.
I hosted my php classes page like http://my.website.com/phpclasses.php
and tried to call it from another host such as:
<?php
include ("http://my.website.com/phpclasses.php");
?>
By the way, the php class page has a class named 'test'
and activated in it by this variable, here is a quick view about it:
phpclasses.php
class test{
somefunctions();
somefunctions();
}
$test = new test();
I requested this page from another website like this:
anotherwebsite.php:
$newclass = new test();
$newclass->somefunctions();
Notice that i've activated the class twice, once in its page, and again in the another website, but failed and returns nothing.
How could it work?
It's a bad idea to include over HTTP unless your printing PHP Code to the browser. Otherwise it will not work.
It's best to include locally:
Class.php
class Test{
public function __construct(){
return TRUE;
}
}
index.php
include "Class.php";
$Class = new Test();
Both files are located on the same server (same directory).. if including in other directories, add correct path to the file:
include "/Core/Class.php";
Being interpreted as
/ - Root Directory
Core - Sub directory
Class.php - File name
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.
I am stumped right now. In my last post about this question the answer was to use a singleton to make sure an object is only initiated 1 time but I am having the opposite problem.
If I have a file called index.php and then I include these files into it, class1.php, class2.php, class3.php, class4.php.
In index.php I will have,
<?PHP
$session = new Session();
require_once '/includes/class1php';
require_once '/includes/class2.php';
require_once '/includes/class3.php';
require_once '/includes/class4.php';
?>
then in all 4 of the test files I will try to access a method called get() from the session class, assume the session class file is already included into the index.php page as well.
Now if I try to use...
$testvar = $session->get($var1);
in any of the test class files I will get this error
Fatal error: Call to a member function get() on a non-object
the only way the code works without an error is if I use
$session = new Session();
in every file.
How can I fix/avoid having to initaite the class in every file when it is already initated in the index.php file?
the goal is to let me initiate a class in 1 file like index.php and then include the class files into that page, the catch is most of the classes use methods from other classes so would be nice if I didn't have to initiate every class in every file
Without seeing the code it's hard to tell, but I think I can make some assumptions. correct me if I'm wrong:
EDIT: So post your source so we can stop speculating
1) The files you are including are class files. in other words, they contain something like:
class a
{
function a(){}
function b()
{
}
}
2) You aren't trying to execute code in the class files, at load time, but at some later time by instantiating them
i.e.
require("class.a.php");
$myA = new a();
$a->b();
If you are trying to reference your session variable inside those classes, then you have a scope issue. A variable declared outside a class definition can't be used inside the class, unless it is declared as a global var inside the class.
class a
{
function a(){}
function willFail()
{
$session->doSomething(); //fails
}
function b()
{
global $session;
$session->doSomething(); //succeeds
}
}
Even then, you probably don't want to do that, but instead you should pass in your session as a variable if the class needs access to it:
class a
{
function a(){}
function b($session)
{
$session->doSomething(); // yay!
}
}
You could have a base class they all all extend from
Example
class test1 extends Base {
public function doSomething() {
$this->session->get('something');
}
}
class Base {
protected session;
public function __construct() {
$this->session = new Session();
}
}
You're kind of thinking about it backwards. Any file that will use the session object will need to include the file containing that class definition. The alternative is to use __autoload to pull the class in:
function __autoload($classname)
{
if ($classname == 'Session')
{
include_once 'Session.php';
}
}
EDIT : you'll need to put the file containing that autoload into every file that will use it.