How to include/require file trough function PHP? - php

I have 2 files, class.inc.php and index.php.
class.inc.php contains Myclass and few functions, index.php file spits out functions from class.inc.php.
Now I need to create a function which will include/require a file and that function should actually require that file in index.php not in class.inc.php.
Yes I know I can place my file in a function and call it that way but we have to keep it in files because of some future MVC overrides. I do not want to include a file in index.php directly either if all possible. So is there a way to do this?
In my index.php I should be able to do this:
Myclass::include(PARAMS);
and that should include a file name params.php located somewhere else.
I tried this in class.inc.php
abstract class Myclass {
static function load($filename){
require_once $filename;
}
}
and this in
index.php
Myclass::include(PARAMS);
but none of my variables from params.php are visible in index.php because they seem to be in class.inc.php.

include, require and friends basically act as though you had copied-and-pasted the contents of the file to that location. So if you run them in a function, any "bare" variables, which would be global if you ran the file on its own, are instead local to that function.
Generally speaking, the answer in modern PHP code is simply not to use any global variables - a file should contain only functions, or better still, only namespaces and classes, with all the variables wrapped up in those.
If you really need to have global variables, however, you can use the global keyword either in your include function or at the top of the included file.
So for instance if your included file defines a variable $config which needs to be accessed elsewhere, at the top of the file you can write global $config; to push it out of any scope you're in when you include/require it.

Related

Add multiple class files before executing PHP [duplicate]

I'm new to PHP, so for example if I have a parent file that include the 2 child files:
include_once('includes/child1.php');
include_once('includes/child2.php');
If child2.php have a class Test with a function test_function:
class Test
{
static function test_function() {
}
}
then can we access this test_function in child1.php like this?
public static function initialize() {
Test::test_function()
}
and if it can, why does it not produce an error since child1.php is included before child2.php(note: I'm coming from Javascript perspective)
No code in child1 or child2 is actually being called. You're just defining some classes and functions, but nothing is calling any of these functions. Test::test_function() is never ever being evaluated, hence it cannot throw any error.
In general: yes, order matters. Everything you're trying to call needs to be defined before you call it. In this case, you're not calling anything, hence it's irrelevant.
Each file should take care of its own dependencies. I.e., child1.php should include (or better: require) child2.php itself if its code depends on it. Don't put the burden of including dependencies on the eventual user of child1.php, this just makes things extremely complicated.
In fact, you should be using autoloading, which will include all necessary files just in time as needed without you having to worry about the complexities of multiple include statements.
You can think of the include family ( include_once, require, require_once ) as a cut and paste type operation. If you follow just envision php creating one big file, pasting the content from each include call ( in the top down order of execution ).
So you might have
index.php
includes.php
functions.php
And if you do this in index
include 'includes.php'
some_function();
And then in includes.php
include 'functions.php'
And then in functions php you have a function some_function(){} you can use this in the index file after the include, php will see it like this
include 'includes.php'
include 'functions.php'
some_function(){}
some_function();
In your example above you would not be able to call the class because you are calling it before including it. Like this
//include_once('includes/child1.php');
Test::test_function();
//include_once('includes/child2.php');
class Test
{
static function test_function() {
}
}
However that said I notice you defined a "method" around your call to Test::test_function() that method would need to be wrapped in a class to work, if that was the intended way then it depends when you instantiate that class, you must do that after the Test class is defined. So for that case we will assume that that method is in a class
class Test2{
public static function initialize() {
Test::test_function()
}
}
Now if you use this class back inside of the parent file or anywhere after the include of child2.php then it will work, so in the parent file if you do this.
include_once('includes/child1.php');
include_once('includes/child2.php');
Test2::initialize();
You would think of this as a big file like this
class Test2{
public static function initialize() {
Test::test_function()
}
}
class Test
{
static function test_function() {
}
}
Test2::initialize();
It should be fine. You just cant call it before it is defined. Make sense?
All that said, I would strongly suggest looking into a PSR autoloader, that is the standard way of including classes these days.
Here is a good post on the topic
http://www.sitepoint.com/autoloading-and-the-psr-0-standard/
Update explination
I'll try to make this as simple as I can. The way PHP works is it loads a file and parses the code, this basically means it just checks the formatting for syntax errors or typos and any new functions or class definitions ( it only registers the names of that new stuff and checks the syntax ). Once that is done and passes it starts to execute the code from top to bottom.
Now when including a file it can't parse it right away because it needs to execute the includes, which it does not do during the initial parsing. After it runs the include it parses the new chunk of code, and then continues executing that new code from top to bottom until the end of the included file at which point it returns to the original file and continues on from the include deceleration.
So while it seems different that you can run a function before defining it in the same file, but not in an included file, it is actually the same behavior. This is because it needs to execute the file to know the functions or code that is in it. So if you call the function before the include, PHP hasn't had a chance to even look in the file yet. Some of this is because you could put an include in an if statement and then PHP would not need to include the file.
What it doesn't do is, parse the file run all the includes and then run the code. I hope that clarified how the process flow works.

how to include a php file inside a public function in Joomla?

I want to include/require_once a PHP file inside a template with the help of a class. It's not including the file as it should be. Only showing the top html part of the file.
In place of JPATH_BASE, I have tried other options also.
class xyz {
public function loadfile($block) {
require_once JPATH_BASE.'/templates/'.$block.'.php';
}
}
$app = new xyz();
$app->loadfile(top);
A help will be very much appreciable.
When you include a file inside a function, remember that it will be executed in its context, which is very likely to break some things for some code. (for example all globals will be undefined without calling global statement before)
For example, consider you add this to your class xyz:
private function test() {
echo 'test';
}
Now, in the included file you can put:
<?php
$this->test();
Now if you load this file using this class, test will be outputted.
The question is why do you want to load files with a help of the class and a function and if it's really neccessary.
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.
(https://php.net/manual/en/function.include.php)
(also, about only top part of the page being shown, check the file that is being included, what it really contains; also check for errors in your server log, they will let you more easily spot the issue)

Can you pass values to included files in PHP without using globals?

A pattern I tend to use often in PHP is setting a few globals (such as $page, $user, $db, etc), and then including a file which uses those globals. I've never liked the idea of using globals for this, though, so I'm looking for a better way.
The obvious solution is to define a class or function in the subfile, and call it after the file is included. There are cases where that can't work though, such as this:
// Add entries to a URI table from each section of the site
global $router;
$router = new VirtualFileSystem();
$sections = array('store', 'forum', 'blog');
foreach($sections as $section)
include dirname(__FILE__) . $section . '/routing.php';
// Example contents of 'forum/routing.php'
// implicitly receive $router from caller
$router->add('fourm/topic/', 'topic.php');
$router->add('forum/topic/new/', 'new_topic.php');
// etc
If I tried to wrap each routing.php in a function and call them each with $router as an argument, the same function name would clash after being defined in multiple files.
I'm out of ideas. Is there a better way to pass variables to included files without polluting the global namespace?
include and its siblings are basically just copy-paste helpers, and the code inside them shares scope with the calling block - as if you'd copy & paste it just where the include statement is. The sane way of using them is to think of them the same way you'd use #include in C or using in C# or import in Java: import some code to be referenced later on. If you have code in the included file that needs parameters, then wrap it in a function, put the parameters in the function arguments, use include_once at the top of the including file, and call the function with the parameters you want, wherever you need to. No globals required. As a rule of thumb, in regular operation, putting any code that "does" something (executes statements in the global scope) in an included file is best avoided IMO.
No, there is not. You're not passing variables to included files anyway. The code that is included behaves as if it was written where the include statement is written. As such, you're not passing variables into the included file, the code in the file can simply use the variables that are in scope wherever the include statement is located.
In your case the contents of forum/routing.php are not really standalone code, they're code snippets that depend on a very specifically set up scope to function correctly. That's bad. You should write your includable files in a way that does not couple them to the including code. For example, you could make your Router a static class and call it statically in forum/routing.php:
require_once 'virtual_file_system.class.php';
VirtualFileSystem::add('forum/topic/', 'topic.php');
As long as there is a class VirtualFileSystem in your app, this will work, and won't pollute the namespace any more than it already is anyway.
just isolate includes in a function:
function add_entries_to_router($router, $sections) {
foreach($sections as $section)
include dirname(__FILE__) . $section . '/routing.php';
}
$router = new VirtualFileSystem();
add_entries_to_router($router, array('store', 'forum', 'blog'));
You can try an OOP way by making a Configuration class as a singleton and retrieving it when you need it.
You could define magic methods for __get and __set to add them to an private array var and make the constructor private.
I usually define as constant only the path to my src project in order to load class files quickly and properly (and use some SPL too).
But I agree with #tdammers about the fact that an include keep the environment variables like if you were on the caller file (the one who makes the include).

PHP class referencing confusion across multiple files

I have an index.php file that has 3 includes
<?php
require_once('mod.php');
$mod = new Mod();
require_once('start.php');
require_once('tools.php');
....some code....
?>
I need to be able to reference the $mod object inside the start.php and tools.php.
How do I pass that object to be referenced by those 2 other require files?
Basically the mod.php is a class that has an array list generated in its __construct(). I want to use that array list data inside the startup.php and tools.php file but not sure how to pass in the existing one without calling "new" inside both of those files separately which doesn't do what I need since it resets everything.
Thanks!
It looks like you're using require() calls not for dynamic functionality loading (get a class definition in), but as something like a function call. Don't. Avoid global variables like a plague.
Side note: Instead of worrying about doing the require() calls in the right order to get your classes defined, I'd encourage you to look at Autoload functionality in PHP 5. It allows you to define which classes are defined in which file, and load those files on-demand when the classes are requested.
First of all use some autoloader. Dozens of require on the top of the file are annoying and needless.
You don't have to pass any references to other files. require works like "copy-paste-execute" so $mod will be available in that file.
#index.php
$mod = new Mod();
include 'file.php';
#file.php
$mod->doSth(); // works file!
Your problem is probably variable scope. If you need to use $mod inside another object (the fact that its source (class) is in another file doesn't matter) pass reference to $mod as a constructor argument, pass it using a special setter ($obj->setMod($mod); $obj->doSth();) or use more complex but better solution like Dependency Injection Container (sample implementation).
Doing require (or require_once, include, or include_once), simply includes and evaluates the code. The variable scope is inherited from the point at which the code is imported.
As an example, using your code:
<?php // index.php
require_once('mod.php');
$mod = new Mod();
require_once('start.php');
And the include:
<?php // start.php
$mod->arrayList(); // $mod is the object created in index.php
The mod should be available in those other files...if you need it in a function or class, use the global keyword, like:
function test() {
global $mod;
print $mod->list;
}

PHP global include?

I have a seperate PHP file I include that has a several important functions on it. I also have a file called variables.php which I include into each function so I can call some important variables too. Is there a way to just call variables.php at the top of the page, instead of inside each function manually? I just thought it would be easier if there was a way to do like a 'global' include or something.
You can set auto_prepend_file in the INI or .htaccess file to automatically include a file.
Well, if they are constant variables (AKA they don't change) you can define a constant instead
define("CONSTANT_NAME", "constant_value");
Or as of PHP5.3
const COSTANT_NAME="constant_value";
Then you can access them in every function
function test(){
echo CONSTANT_NAME;
}

Categories