Also worth noting, I use a extreme-logger when doing intense troubleshooting. It basically does a debug_backtrace and logs certain info. I noticed on some older PHP installs (<5) I had to prepend __FILE__ and __LINE__ with ''. just to force PHP output a string. Specifically I was loading those two in an array which were concat'd onto a log file eventually.
example:
if($a['debug']){$of->logger(array('file'=>__FILE__,'line'=>''.__LINE__,'data'=>$sql_data_array));}
Constantes magiques
PHP fournit un grand nombre de constantes magiques. Certaines constantes sont définies par différentes extensions, et ne seront présentes que si ces extensions sont compilées avec PHP, ou bien si l'extension a été chargée dynamiquement.
Il y a huit constantes magiques qui changent suivant l'emplacement où
elles sont utilisées.
Par exemple, la valeur de __LINE__ dépend
de la ligne où vous l'utilisez dans votre script.
Ces constantes spéciales sont insensibles à la casse.
| Nom | Description |
|---|---|
__LINE__ |
La ligne courante dans le fichier. |
__FILE__ |
Le chemin complet et le nom du fichier courant. Si utilisé pour une
inclusion, le nom du fichier inclus est retourné.
__FILE__ contient toujours le chemin absolu
pour les liens symboliques.
|
__DIR__ |
Le dossier du fichier. Si utilisé dans une inclusion, le dossier du fichier inclus sera retourné. C'est l'équivalent de dirname(__FILE__). Ce nom de dossier ne contiendra pas de slash final, sauf si c'est le dossier racine. (Ajouté en PHP 5.3.0.) |
__FUNCTION__ |
Le nom de la fonction. Cette constante retourne le nom de la fonction comme il a été déclaré (sensible à la casse). |
__CLASS__ |
Le nom de la classe courante. Cette constante retourne le nom de la classe comme il a été déclaré (sensible à la casse). Le nom de la classe contient l'espace de nom dans lequel cette classe a été déclarée (i.e. Foo\Bar). Notez que depuis PHP 5.4, __CLASS__ fonctionne aussi en Traits. Lorsqu'une méthode Trait est utilisée, __CLASS__ est le nom de la classe que Trait utilise en interne. |
__TRAIT__ |
Le nom Trait (Ajouté en PHP 5.4.0). Depuis PHP 5.4, cette constante retourne le Trait comme il a été déclaré (sensible à la casse). Le nom Trait inclut l'espace de nom dans lequel il a été déclaré (e.g. Foo\Bar). |
__METHOD__ |
Le nom de la méthode courante. Le nom de la méthode est retourné comme il a été déclaré (sensible à la casse). |
__NAMESPACE__ |
Le nom de l'espace de noms courant (sensible à la casse). Cette constante est définie au moment de la compilation (Ajouté en PHP 5.3.0). |
Voir aussi get_class(), get_object_vars(), file_exists() et function_exists().
tc0nn
15-May-2012 07:55
david at thegallagher dot net
22-Feb-2012 02:19
You cannot check if a magic constant is defined. This means there is no point in checking if __DIR__ is defined then defining it. `defined('__DIR__')` always returns false. Defining __DIR__ will silently fail in PHP 5.3+. This could cause compatibility issues if your script includes other scripts.
Here is proof:
<?php
echo (defined('__DIR__') ? '__DIR__ is defined' : '__DIR__ is NOT defined' . PHP_EOL);
echo (defined('__FILE__') ? '__FILE__ is defined' : '__FILE__ is NOT defined' . PHP_EOL);
echo (defined('PHP_VERSION') ? 'PHP_VERSION is defined' : 'PHP_VERSION is NOT defined') . PHP_EOL;
echo 'PHP Version: ' . PHP_VERSION . PHP_EOL;
?>
Output:
__DIR__ is NOT defined
__FILE__ is NOT defined
PHP_VERSION is defined
PHP Version: 5.3.6
Anonymous
27-Dec-2011 09:44
Further clarification on the __TRAIT__ magic constant.
<?php
trait PeanutButter {
function traitName() {echo __TRAIT__;}
}
trait PeanutButterAndJelly {
use PeanutButter;
}
class Test {
use PeanutButterAndJelly;
}
(new Test)->traitName(); //PeanutButter
?>
jrivero24 at yahoo dot es
05-Aug-2011 04:37
When __DIR__ is not defined, prior 5.3.0:
<?php if ( !defined('__DIR__') ) define('__DIR__', dirname(__FILE__)); ?>
user9 at voloreport dot com
10-Jul-2011 02:33
Note that __FILE__ has a quirk when used inside an eval() call. It will tack on something like "(80) : eval()'d code" (the number may change) on the end of the string at run-time. The workaround is:
$script = php_strip_whitespace('myprogram.php');
$script = str_replace('__FILE__',"preg_replace('@\(.*\(.*$@', '', __FILE__,1)",$script);
eval($script);
chris dot kistner at gmail dot com
20-Apr-2011 07:16
There is no way to implement a backwards compatible __DIR__ in versions prior to 5.3.0.
The only thing that you can do is to perform a recursive search and replace to dirname(__FILE__):
find . -type f -print0 | xargs -0 sed -i 's/__DIR__/dirname(__FILE__)/'
Jamie
02-Mar-2011 02:13
Note that as mentioned, __FILE__ resolves any aliases. Other real path information, such as $_SERVER["SCRIPT_FILENAME"], doesn't.
__FILE__ => /volume1/web/mysite/admin/inc/includeFile.inc.php
$_SERVER["SCRIPT_FILENAME"] => /var/services/web/mysite/admin/products.php
If you need to compare one with the other, use
realpath($_SERVER["SCRIPT_FILENAME"])
stefan at efectos dot nl
08-Nov-2010 06:58
When __DIR__ is not defined, you can also use this workaround to generate it:
<?php
if(!defined('__DIR__')) {
$iPos = strrpos(__FILE__, "/");
define("__DIR__", substr(__FILE__, 0, $iPos) . "/");
}
?>
Keep in mind this sets __DIR__ to the directory you are running this snippet from.
madboyka at yahoo dot com
10-Sep-2010 09:37
Since namespace were introduced, it would be nice to have a magic constant or function (like get_class()) which would return the class name without the namespaces.
On windows I used basename(__CLASS__). (LOL)
Anonymous
08-Aug-2010 05:39
__DIR__ befor PHP 5.3.0
<?php
if (!defined('__DIR__')) {
class __FILE_CLASS__ {
function __toString() {
$X = debug_backtrace();
return dirname($X[1]['file']);
}
}
define('__DIR__', new __FILE_CLASS__);
}
?>
me at jamessocol dot com
25-Jun-2008 11:11
We need an eighth magic constant, something along the lines of __STATIC__. This should return the name of the class from which a static method was called, regardless of where in the inheritance tree the method was defined.
PHP 5.3 has the new use of the static keyword which will help, but it isn't perfect. You still have to repeat yourself frequently.
For example, trying to implement Active Record:
<?php
// In PHP 5.3
class Model
{
public static function find()
{
echo static::$class;
}
}
class Product extends Model
{
protected static $class = __CLASS__;
}
class User extends Model
{
protected static $class = __CLASS__;
}
Product::find(); // "Product"
User::find(); // "User"
?>
<?php
// With __STATIC__ keyword. (Would be better.)
class Model
{
public static function find()
{
echo __STATIC__;
}
}
class Product extends Model {}
class User extends Model {}
Product::find(); // "Product"
User::find(); // "User"
?>
[EDITED : Use get_called_class()]
php at kennel17 dot co dot uk
20-Jun-2007 12:29
Further to my previous note, the 'object' element of the array can be used to get the parent object. So changing the get_class_static() function to the following will make the code behave as expected:
<?php
function get_class_static() {
$bt = debug_backtrace();
if (isset($bt[1]['object']))
return get_class($bt[1]['object']);
else
return $bt[1]['class'];
}
?>
HOWEVER, it still fails when being called statically. Changing the last two lines of my previous example to
<?php
foo::printClassName();
bar::printClassName();
?>
...still gives the same problematic result in PHP5, but in this case the 'object' property is not set, so that technique is unavailable.
php at kennel17 dot co dot uk
20-Jun-2007 11:12
In response to stangelanda at gmail dot com, (who suggested a possible fix to get the actual class name of the object, when being called statically).
in PHP5, this fix no longer works.
Here is some example code:
<?php
function get_class_static() {
$bt = debug_backtrace();
$name = $bt[1]['class'];
return $name;
}
class foo {
function printClassName() {
print(get_class_static() . "<br>");
}
}
class bar extends foo {
}
$f = new foo();
$b = new bar();
$f->printClassName();
$b->printClassName();
?>
In PHP4, it outputs
foo
bar
as you described.
However, in PHP5, due to the way the debug_backtrace() function has been modified (see http://bugs.php.net/bug.php?id=30828) the output is now
foo
foo
I have yet to figure out a way to get the original output in PHP5. Any suggestions would be very useful, and if I find an answer I'll post it here.
Tomek Perlak [tomekperlak at tlen pl]
10-Nov-2006 03:16
The __CLASS__ magic constant nicely complements the get_class() function.
Sometimes you need to know both:
- name of the inherited class
- name of the class actually executed
Here's an example that shows the possible solution:
<?php
class base_class
{
function say_a()
{
echo "'a' - said the " . __CLASS__ . "<br/>";
}
function say_b()
{
echo "'b' - said the " . get_class($this) . "<br/>";
}
}
class derived_class extends base_class
{
function say_a()
{
parent::say_a();
echo "'a' - said the " . __CLASS__ . "<br/>";
}
function say_b()
{
parent::say_b();
echo "'b' - said the " . get_class($this) . "<br/>";
}
}
$obj_b = new derived_class();
$obj_b->say_a();
echo "<br/>";
$obj_b->say_b();
?>
The output should look roughly like this:
'a' - said the base_class
'a' - said the derived_class
'b' - said the derived_class
'b' - said the derived_class
stangelanda at gmail dot com
05-Sep-2006 11:17
claude noted that __CLASS__ always contains the class that it is called in, if you would rather have the class that called the method use get_class($this) instead. However this only works with instances, not when called statically.
<?php
class A {
function showclass() {
echo get_class($this);
}
}
class B extends A {}
$a = new A();
$b = new B();
$a->showclass();
$b->showclass();
A::showclass();
B::showclass();
//results in "a", "b", false, false
?>
I tried keeping track of the class manually within the properties, but the following doesn't work either:
<?php
class A {
var $class = __CLASS__;
function showclass() {
echo $this->class;
}
}
class B extends A {
var $class = __CLASS__;
}
//results in "a", "b", NULL, NULL
?>
The best solution I could come up with was using debug_backtrace. I assume there is a better way somehow, but I can't find it. However the following works:
<?php
class A {
function showclass() {
$backtrace = debug_backtrace();
echo $backtrace[0]['class'];
}
}
class B extends A {}
//results in "a", "b", "a", "b"
?>
warhog at warhog dot net
18-Dec-2005 02:33
There is another magic constant not mentioned above: __COMPILER_HALT_OFFSET__ - contains where the compiler halted - see http://www.php.net/manual/function.halt-compiler.php for further information.
vijaykoul_007 at rediffmail dot com
21-Sep-2005 11:59
the difference between
__FUNCTION__ and __METHOD__ as in PHP 5.0.4 is that
__FUNCTION__ returns only the name of the function
while as __METHOD__ returns the name of the class alongwith the name of the function
class trick
{
function doit()
{
echo __FUNCTION__;
}
function doitagain()
{
echo __METHOD__;
}
}
$obj=new trick();
$obj->doit();
output will be ---- doit
$obj->doitagain();
output will be ----- trick::doitagain
karl __at__ streetlampsoftware__dot__com
03-Mar-2005 02:39
Note that the magic constants cannot be included in quoted strings.
For instance,
echo "This is the filename: __FILE__";
will return exactly what's typed above.
echo "This is the filename: {__FILE__}";
will also return what's typed above.
The only way to get magic constants to parse in strings is to concatenate them into strings:
echo "This is the filename: ".__FILE__;
csaba at alum dot mit dot edu
03-Mar-2005 05:04
Sometimes you might want to know whether a script is the top level script or whether it has been included. That could be useful if you want to reuse the routines in another script, but you don't want to separate them out. Here's a way that seems to be working for me (for both Apache2 module and CLI versions of PHP) on my Win XP Pro system.
By the way, if __FILE__ is within a function call, its value corresponds to the file it was defined in and not the file that it was called from. Also, I used $script and strtolower instead of realpath because if the script is deleted after inclusion but before realpath is called (which could happen if the test is deferred), then realpath would return empty since it requires an extant file or directory.
Csaba Gabor from Vienna
<?php
if (amIincluded()) return; // if we're included we only want function defs
function amIincluded() {
// returns true/false depending on whether the currently
// executing script is included or not
// Don't put this function in an include file (duh)!
$webP = !!$_SERVER['REQUEST_METHOD']; // a web request?
$script = preg_replace('/\//',DIRECTORY_SEPARATOR,
$_SERVER['SCRIPT_FILENAME']);
return ($webP) ? (strtolower(__FILE__)!=strtolower($script)) :
!array_key_exists("_REQUEST", $GLOBALS);
}
?>
lm arobase bible point ch
08-Dec-2004 03:17
in reply to x123 at bestof dash inter:
I believe, this is not a bug, but a feature.
__FILE__ returns the name of the include file, while $PHP_SELF returns the relative name of the main file.
It is then easy to get the file name only with substr(strrchr($PHP_SELF,'/'),1)
claude at NOSPAM dot claude dot nl
18-Jul-2004 10:29
Note that __CLASS__ contains the class it is called in; in lowercase. So the code:
class A
{
function showclass()
{
echo __CLASS__;
}
}
class B extends A
{
}
$a = new A();
$b = new B();
$a->showclass();
$b->showclass();
A::showclass();
B::showclass();
results in "aaaa";
ulrik
04-Mar-2004 08:44
note that __FUNCTION__ define gives the the function name in lowercase
warhog at warhog dot net
06-Feb-2004 01:49
just to read out the filename of the currently proceeded file use
<?php basename(__FILE__); ?>
hixon at colorado dot edu
15-May-2003 07:21
You can use the following in files that you want to include, but not run directly. The script will exit if it's run as the top-level script, but will not exit if it's included from another script. Of course this won't work in the command line mode.
if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) {
exit;
}
kop at meme dot com
13-Feb-2003 04:34
The keywords TRUE and FALSE (case insensitive), which represent their respective boolean values, are worth noting here.
darwin[at]buchner[dot]net
14-Mar-2002 05:54
As of version 4.0.6, there is also a handy predefined DIRECTORY_SEPARATOR constant which you can use to make you scripts more portatable between OS's with different directory structures.
