How can I find what is calling a routine

I’m looking for advise on how to find what is calling a routine located in an include file. Maybe it has something to do with debug backtrace but I’m not sure how or if that is the right choice. Here’s the situation:

I have an include file, initialize.php that is included in multiple entry-point landing page scripts. afik every starting landing page script defines a constant ACCESS that is used in the include file. The constant ACCESS is used in the include file. So conceptually I have landing page << include such as:

cart.php << include initialize.php
view.php << include initialize.php
member.php << include initialize.php

99% of the time everything is fine, but every once-in-a-while I get an error_log entry such as:

PHP Warning:  Use of undefined constant ACCESS - assumed 'ACCESS'  in .../initialize.php on line 227

How can I find out what the calling script is that is calling initialize.php but is not defining ACCESS? This has to be on a live site because I can’t replicate it on a dev site. And it happens very infrequently so I don’t know the scenario that it happens in. And since it’s on a live site I can’t have anything print to the screen, so I would like to have it make an entry in the error_log with the necessary information.

Conceptually I’m thinking I could modify the code around line include.php:227 to test if ACCESS is defined, and if not then output some type of backtrace to error_log, but I don’t know if that is the right approach or how to do it.

So I’m looking for some advice on a good approach and how-to.

Thanks

Try finding all include ‘initialise.php’; and add this script:

<?php
//
if( defined('ACCESS') ):
  include 'initialise.php';
else:
  echo __file__ .' : ' .__line__;
  exit;
   // or log debug stuff
endif;

Edit:
It is possible ‘initialise.php’; is called directly and advisable to test for a ‘OK2USETHISFILE’ CONST which is defined in a top level PHP file.

Modern practise to prevent direct access and to only have a single entry ‘index.php’ file which accesses all other files which are located above_the_root

You install XDEBUG and set a breakpoint in your IDE.Specialized IDEs may also provide the ability to set conditions on breakpoints so you do not have to debug every call.

EDIT: Okay, lets try that in a cohesive manner.

Why are you getting to line 227 without checking the existence of a constant named “ACCESS”? Shouldn’t that be lines 1-3, with a die() being one of those lines? What exactly is the purpose of that defined constant, if not that?

if(!defined('ACCESS')) {
  die();
}

I’ve never used XDebug… is it possible to do what you suggest on a live site? The reason I ask is that I’ve only ever seen this undefined constant on a live site with visitors accessing it. I’ve never been able to replicated it in a dev environment. So obviously I’m missing something in the problem replication (as the saying goes… you don’t know what you don’t know.) So I have to implement something on a live production site to try and capture what the calling routine is that drops into the include file and generates the undefined error.

XDebug adds considerable overhead, so it’s advised not to run it in production. Also, you need to know when a request with the error will occur so you can debug it as it happens. Not really feasible I would think.

I’d propose the following:

  1. Do a search over your entire project and check for ACCESS and check for all occurences if it is defined at that point
  2. Add an error handler in production that will catch exactly that error and dump it to the log.
    See set_error_handler, debug_backtrace and error_log.

Have you tried calling “initialise.php” on the live site?

from my previous post

It is possible ‘initialise.php’; is called directly and advisable to test for a ‘OK2USETHISFILE’ CONST which is defined in a top level PHP file.

Modern practise to prevent direct access and to only have a single entry ‘index.php’ file which accesses all other files which are located above_the_root

Next time you find an error in the “error.php” log file, take a note of the date/time. Open the “access.php” log file and find the corresponding URL request along with the Http Response code.

Thanks everyone for all the helpful tips and ideas. :grin: Compiling them together this is what I’ve put in the included initialize.php file just before line 227 to try and capture the error perpetrator. It watches for a visit to that code area without a defined “ACCESS” constant and then writes some backtrace info to error_log.

if (!defined('ACCESS')) {
	error_log( 'ACCESS Value is ' . ACCESS . ': ' . basename($_SERVER['SCRIPT_FILENAME']) . '>>' .basename( __file__) .' : ' .__line__);
	error_log( json_encode(debug_backtrace()));
}

This has already given me some direction as to the source of the problem.

Asking to send the value of ACCESS when the if condition has determined that ACCESS is not defined will cause problems and most likely not send a report to the error log.

In reality that first part (error_log( 'ACCESS Value is ’ . ACCESS . ': '…) is kinda bogus because as you state, ACCESS is not defined. What I’ve found actually happens is that since it is not defined php assumes a value of ‘ACCESS’ and outputs that in the error_log. (e.g. ‘ACCESS Value is ACCESS’).

I’m most surprised :slight_smile:

Did you note the date/time stamp in the error log and also the corresponding URL and http response code in the access.log?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.