Page 1 of 1

PHP Source listing suggestion

Posted: Fri Aug 11, 2017 4:25 am
by sfws
The PHP parser runs on the web server, converting a source PHP script to pure HTML and the browser only sees that resulting web page. This is useful in that it allows the programmer to include reference in the PHP to items (such as access to databases) that you might not want end-users to see, and it protects the interllectual property of that programmer/designer/company.
However, programmers sometimes are happy to share their scripts and may therefore include a self down-loader like this one, so that by entering a particular query-string an end-user can see the PHP source:

Code: Select all

if ( isset($_REQUEST['source']) && strtolower($_REQUEST['source']) == 'view' ) {
 header('Pragma: public');
 header('Cache-Control: private');
 header('Cache-Control: no-cache, must-revalidate');
 header('Content-type: text/plain');
 header('Accept-Ranges: bytes');
 header("Content-Length: $download_size");
 header('Connection: close');

There does not appear to be consistency over the query-string used to initiate the source list, that example uses "source=view" as in cumulswebtags.php?source=view.
Other scripts use "view=source", "sce=view", "view=src", and (e.g.) "". One contributor on this forum uses the more obscure "?view=getorfmiland" if you want to see the source of his widely used script.

That approach has a major disadvantage, typically the main PHP script generating a web page will use one or more "require ..." and/or "include ..." instructions that bring in snippets of common code onto the page (e.g. for the access to database, for standard header or footer content, or to bring in shared functions or shared arrays). If you try each of the query-strings I have just quoted on a page you are looking at on the internet, it may be ignored and the page just reloaded, it might list the main script producing the web page, or it might list the first included script that contains a self-downloader snippet. It depends which script file includes the above code, and if more than one of the php script files includes the above code, the first file parsed that includes the code is actually listed. What you are never able to do is choose which file, if any, will have its source listed!

I have implemented an alternative, a way to view the source of any of the scripts making up any web page, and thought I would share it, in the vain(?) hope that others might consider it as 'best practice' to adopt for their script writing. As I report at, I have by incorporating my script snippets described below made it possible for you to display the source of any of my METAR decoding scripts that are being used on PaulMy's web site.

* I wanted to be able to decide script by script whether its source could be viewed (to exclude those containing passwords or other material that you would expect to remain hidden).
* I wanted to be able to choose which of the various scripts in any web page got listed by selecting the relevant script using a query-string.
* I wanted a way to optionally list the range of possible query-strings (for when I could not remember which scripts were included in a particular web page).
* I needed the downloader to know the path names for each file as my individual scripts are not all in the same directory.
* I wanted to test whether files and functions existed, so that failure to find the down-loader did not affect the working of the rest of the script.

My solution consists of two parts. First a snippet of PHP instructions that I actually paste into each of the PHP scripts that the end-user is allowed to view:

Code: Select all

   #    Just list the PHP source?    Start of common SPAWS snippet.      
   #    Modify URL of calling web page by adding a query-string such as
   #    ?viewSource='xxxxx'" or "?src='xxxxx'" or "?sce='xxxxx'"          
   # to see source for any file xxxxx.php whether main scriptor included file 
   $path = /* put the path to where you have the common script here */;
   if(file_exists($path . '\sourceView.php'))    include_once $path . '\sourceView.php';      
   if(function_exists('add_source')) add_source(__FILE__, basename(__FILE__, '.php'));  # NB use of this magic constant represents the file in which it appears
      if(   isset($_GET['viewSource']) && $_GET['viewSource'] == basename(__FILE__, ".php") or
         isset($_GET['sce']) && $_REQUEST['sce'] == basename(__FILE__, '.php') or
         isset($_REQUEST['src']) && $_REQUEST['src'] == basename(__FILE__, '.php')         
            if(function_exists('display_source'))   display_source (basename(__FILE__, '.php'));
   #    End of common snippet to list source call         

Note that I recognise that there is not going to be agreement as to which query-string selector is used so to make it easy to list my sources, I therefore offer three different selector name alternatives:
*viewSource=(base file name)
*src=(base file name)
*sce=(base file name)

The second part is in a separate file, the "include_once $path . '\sourceView.php';" in the above snippet loads it. Because so many of my PHP scripts use it, my "sourceView.PHP" includes several array and function declarations that I find useful to save me typing them into individual scripts, but it does not include the snippet above as I choose not to share its own content! However, it basically has the down-loader that I quoted at the start of this post and I show most of the code below as I would be pleased if this was used more widely to make it easier for amateurs experimenting with programming like myself to see code. However, it did need an eureka moment for me to work out that I could deal with my path-name uncertainty by storing the path name in an array together with a shorter-name appropriate to use in a query-string, so while I am happy for anybody else to use my script snippet, please don't use my path name idea for your own profit! The two functions add_source(x,y) and display_source(y) referenced in the snippet above are also defined together with a global array. I can use an optional global variable (that I assign an arbitrary value to, in one of the scripts making up the page, when I want to be prompted with list of query-strings available):

Code: Select all

function display_source($filenameRequest)   {
   global $fileNameArray; // see other function for how this array set up
   $download_size = filesize($filenameRequest . ".php");
        header('Pragma: public');
        header('Cache-Control: private');
        header('Cache-Control: no-cache, must-revalidate');
        header("Content-type: text/plain");
        header("Accept-Ranges: bytes");
        header("Content-Length: $download_size");
        header('Connection: close');
   echo "<section class='b_LH'>"; // define background in CSS using a class so easier to read listing
   $fileName = $filenameRequest . ".php";
   echo "</section>";// end defined background

function add_source($pathName,$fileName)
   global $fileNameArray, $list_sources_available, $list_query_string;
   // Note shared array holding path-names and file-names, and note optional variable which if included in calling script will produce output in final global array
   if(!isset($list_query_string)) $list_query_string = array();
   if(isset($list_sources_available))   $list_query_string[] = "<small>Use query-string <span class='blue'>?src=" . $fileName ."</span> to output PHP source for " . $pathName ." &nbsp; &nbsp; </small>";
   // Tailor the 'src' to whatever you prefer
   if (!isset($fileNameArray) or !in_array($fileName, $fileNameArray)) $fileNameArray["'" . $fileName . "'"] = "'" . $pathName . "'"; // If current script not already in array, add it