PHP reuse: What are the differences between "include files" and "functions"? - php

What are the differences between "include files" and "functions" for reusing code in PHP?
I can enumerate 1 difference: when using a function, the caller script don't have access to the function local vars but when including the includer script has access to the local vars of the included script.
What are other differences?
When should i use "functions" and when should i use "include files"?
For DB connection which one is usually used?

Functions are callable blocks of code. Usually created by the developer when that certain block of code is used multiple times. Instead of writing the same code in multiple places, you create a function and call it when needed.
Also, some developers create functions to make a certain task distinct in the code for readability and understandability. They use functions as "labels" as to what a certain block of code does. For example, I'd create a readFile() function for a certain block of code that reads files.
Includes on the other hand "merges" a file into the calling file as if it were coded into that file. This makes whatever was declared in the other file available in the current file in the scope that called it.
As for what to use, you use both.
To separate DB connection code from the current file, I'd create a DB Class in another file (like dbcon.php) containing all the properties and methods (functions) needed to interface with the DB.
Then, in the file that needs the DB connection (like index.php), it should use include to "merge-in" the file containing the DB Class for index.php to use the class definition.

It seems an obvious question, but it's interesting anyway to share our experiences.
Inclusion of configuration files (constants i.e.) should be done with require_once. Because without it your system cannot works (require), and it should be included only one time (once).
So... class, DB configuration, constants and core files should be inserted by require_once and not with include, because if some file missing, it throws a fatal error and stop execution, preventing errors chain.
So, when we can use include?
include should be used for inclusion of part of code more more complex (with other inclusion for example) and with part of code that's no mandatory or essential for your system. You can think, for example, to an inclusion of one module for the view. (include a php file that process a tpl file). I thinking when I work on system with other developer: some part are shared (i.e. Database) and some part are local. If I modify something in shared part that causes a failed inclusion for other developers, it not cause a fatal error for they. (it's just an example)
Now: when I should use function instead?
When you write a lot of function you can use ONE single file included (or, better, required) and call one of this function when you want. Besides the code inside all functions is encapsulated preventing annoying conflicts with other part of code (and believe me: it happens very often and it's not always easy to find the error)
Benefit: one single file for many functions, and all code encapsulated.

Related

PHP uninclude or reinclude file in interactive mode

I'm testing some database related functions in interactive mode.
The first thing I did is to include the testing file, let's say database.php
Then I can make change to the database by a function call.
The question is, when I make any changes to database.php, I have exit PHP interactive mode, re-enter, include the testing file again.
I'm seeking a way to reload the include file during the interactive mode.
There is no simple method of doing this cause PHP is not built for this job, but there are some things you can take a look at as it might do the job for you. However this all depends on what is in your database.php.
Create a simple function like reset and use PHP's runkit functions to update your include.
If your database.php contains functions, you need to remove the functions before including it again. If your file has a class defined in it you could try the import function and just call the function that does all this for you but in the end this is all manual labor and it might be simpler to look at other alternatives.
I for one use a auto refresh timer in my browser to refresh the page every # seconds. However I have two screens which makes using this method much easier.
That is something you should never do. It will create double functions, which will create confusion in the PhP interpreter.
You should require files out of your scope, so they are globally available, That way you can reduce the server overhead (memory usage) and reuse the included class directly without requiring it again.
Or you could create an autoloader, which imports the file when needed. If it is already there, it will return the needed instance without the extra overhead. An autoloader keeps track of the already included or required files.
That said, with include or required, you could load files. Instead of required_once or include_once, they keep including files.

How to structure a PHP app to prevent including a library more than once?

Recently I've been facing a specific problem, that of including a file twice (actually a bunch of files twice), but I haven't found the solution to the problem because of the complexity of the system, I've created. Below is the sketch for my file system.
http://flockdraw.com/gallery/view/1976405
See, my main file is connection.php (where the database connection is established), which includes constants.php in another hand. Then I have two files that include connection (and really extend the class, because of different databases and purposes these two files would have): database.php (database operations for users database) and uni_database (database operations for another database I'm using). These two files are used separately by session.php (which uses functions from the database.php class) and uni_class(which uses functions from the uni_database class).
I have to include those two file (uni_class and session.php) to almost any another pages of mine, but when I do so, I include constants and connection twice, which results in errors.
I had a solution to use only one connection to the database, one file for database operations (queries), but then again it doesn't seem logical to me to put the uni_class and session class in one file.
Using an autoloader is probably the best solution. Though you could also use require_once or include_once as those are built-in functions for PHP that do exactly what you need.

Php global variable across the whole project

I'm relatively new to PHP, and I'm looking for a way to define certain objects as globally accessible from throughout the project, from multiple PHP scripts.
In Java, if I've to access some objects globally, I define some public class named Globals , and define the objects that I need to access as static in the Globals class. I then access those objects wherever I need with: Globals.variable_name .
So basically, I need to initialize these global objects only once and then use them whenever I need them..
One use case:
I've a class named Logger that has methods to log certain events in a log file. I need to have 1 Logger instance/object that can be used by all the PHP scripts in the project, whenever they've to log something. I'd rather not have each PHP script using it's own instance of Logger.
The naive Java-like approach I tried, that did not work:
I created a public class named Globals in a separate PHP file (named Globals.php) with one static object of type Logger, named $logHandle. I included this PHP file in all other PHP files where I need this Logger object. I then tried to access this object , using Globals->logHandle from one of the other PHP scripts. This attempt failed miserably.
Is there some similar approach?
Thanks.
PHP is not Java.
In web applications, the PHP environment is initialized for each request - and each request is handled in a different process with it's own memory space. It is possible to share access to data (including serialized objects, but not resources such as database connections and file handles) across different instances. You probably know this already but have not yet realised how it influences the way you write code.
I'd rather not have each PHP script using it's own instance of Logger
Why not?
One very good reason is that allowing multiple processes to write to the same open file handle requires locking to prevent the file getting all mesed up. BUT THIS IS PHP - STOP REINVENTING THINGS FROM SCRATCH. Writing to stderr will append the details to the webserver error log or use the OS syslog facilities - that's what they are there for.
It is impossible to have the same object available to all instances of PHP - you can unserialize an object in all instances - but then it's not the same object. You can run a daemon with a single object which might be accessible to all other PHP instances via a socket connection - but it's not running in the same address space.
If you validly have a class that you want to be universally available via an object with a fixed name, then simply create an instance of the object in each script or via an include file. The approach you tried is the way to go about this (but don't name your objects with reserved words). We don't know why it failed because you didn't provide any error messages or code.
I assume you're asking about common case (now only web-oriented application). And for that - no, you can not define some thing like you've described, in native way. This is the thing that is called superglobals in PHP.
But on the other hand - you need to do that for some reason, not "just because you want it". And, if so - then use configuration file. Create some application configuration file, read it once at start of application (bootstrap) and you'll get all needed values. I'm not saying anything about file structure - it can be xml/ini/yaml/whatever/you/like. But the idea is - to split this logic from application structure itself and use separate file for storing desired values.
Another option is to use some separate PHP file(s) and include it at bootstrap. Define all needed variables/constants in that file(s) and you'll get similar behavior. Note, that in terms of namespaces it's less "global" and you'll need to resolve all that cases manually.
For web-applications, however, one of possible solutions may be using sessions. $_SESSION is a superglobal array and it will behave like you want (i.e. will be accessible from everywhere). But that is not applicable always - and not always you'll want to deal with sessions to store session-independent data.
you can do like this
you said that you have included in all other classes change methods in your global class to static
<?php
class Logger {
public static function log($msg) {
// ...
}
}
you can use it like
Logger::log($msg);
http://www.php.net/manual/en/reserved.variables.globals.php
i think that is what you're after.
To access a static attribute in PHP you need to call it with the Class::$attribute notation, and the static methods need to be called with the Class::method() notation.
The -> notation is used when calling attributes of a class instance.

Why would you want to include/require multiple times?

require and include have the variations require_once and include_once. They prevent the script from loading a file multiple times.
I think I can safely assume, because the functions exist, that there would be cases where you would need the require/include function instead of the require_once/include_once one. But I cannot imagine a case like that. What would that be?
Probably the best example would be when giving output. If, say, you had a snippet of HTML that might appear more than once on various pages, you could put it into a separate file and include it as many times as you wanted.
Moreover, it's often unnecessary to use require_once or include_once. If the file will only be called once (e.g. in __autoload) then the simple functions have less overhead, because PHP doesn't need to keep track of whether the file has been included before.
One may want to use require_once instead of require if you want to have a variable or constant defined only once. This is helpful for making reusable classes in a very large code base that manages dependencies rapidly. Lets say I have a file A that needs a file B but I already include file C that included file B. Since file B was already included, the program does not have to evaluate that code again to properly evaluate file A. This is a case where you may want to include the file only once.
It helps with managing your dependencies

Autoloading from file with several classes

In my project structure I have the usual class per file separation and auto-loading is easy, but now I would like to group some small classes in a a single file, probably a file with the name of the current folder.
now:
|/module
|-Smallclass1.php
|-Smallclass2.php
|-Smallclass3.php
|-Normalclass.php
after:
|/module
|-module.php <-- smallclasses go here
|-Normalclass.php
Now comes the debate.
To autoload one 'SmallclassX' I was thinking to check if SmallclassX.php file exists if not check if module.php exists and if so, check if the class exists inside the file and include it. Including the whole module.php file when I need a single class seems an overhead specially if the file contains many classes. Here they suggest using tokens the check if the class exists, but I'm not sure about it's efficiency, after that I'll need a method to include only the class I need.
Do you think if I get to load only the class I need like I mentioned, will it be also an overhead because of reading the file more that once and looking inside to include the piece of code I want?
You can stack autoloaders using spl_autoload_register, allowing you to first attempt to load the class from a dedicated file, then falling back to including the module file afterwards (and if no autoloader can solve the dependency, error out normally). This will allow you to avoid all hacks by parsing tokens and other items, which will require a lot more than just require-ing the file and seeing what the result is afterwards.
I would however advice you to benchmark this solution. Whether it's more effective will depend on the delay for accessing the files (APC) and the cost of parsing and including each class seperately.
I'll also agree with the other comments, it might be confusing that you have two separate schemes for including classes, and APC will remove most of the cost of having separate files anyway.

Categories