2

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.

sanjeev mk
  • 4,060
  • 4
  • 36
  • 60
  • 2
    Related - [Why globals are evil](http://stackoverflow.com/a/5166527/1607098). Try using [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection) instead – Touki Mar 12 '14 at 09:36
  • Without instantiate the object on the pages you cant access the member data, I would suggest to use static variables in the class Globals and use them as Globals :: varname in the included files. – Abhik Chakraborty Mar 12 '14 at 09:36
  • Keep in mind that in Java, your static instance is actually shared between different servlets because they run in the same VM, whereas in PHP you can share the definitions and the code to create the instances, but you are not sharing the **state** between scripts. – Nate C-K Mar 12 '14 at 09:40

5 Answers5

5

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.

symcbean
  • 45,607
  • 5
  • 49
  • 83
2

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.

Alma Do
  • 35,363
  • 9
  • 65
  • 99
  • I think the point is really just to have one place in the code that creates the logger rather than having to write `$logger = new Logger()` all over the place. – Nate C-K Mar 12 '14 at 09:41
  • I've made my assumptions from _"to define certain objects as globally accessible from throughout the project"_ – Alma Do Mar 12 '14 at 09:42
  • I had tried `$GLOBALS` actually, but that too works only inside 1 script, across all classes inside that script; but not across multiple files. I'll try `$_SESSION` but that too I think will be limited within one script. Yeah, I think as a last resort, I'll have to use some external configuration file. – sanjeev mk Mar 12 '14 at 09:55
  • No. `$GLOBALS` stores variables, defined in _global_ scope - but that doesn't mean "superglobal". Global variables are not available in inner scopes (unless used with `global` keyword, but that's evil - and for me, if you don't know what it is - it's for your good) – Alma Do Mar 12 '14 at 09:57
1

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);
Sivagopal Manpragada
  • 1,282
  • 12
  • 32
0

http://www.php.net/manual/en/reserved.variables.globals.php

i think that is what you're after.

bountyh
  • 165
  • 9
0

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.

Community
  • 1
  • 1
gpopoteur
  • 1,489
  • 10
  • 17