When did classes arrive to php?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
JohnBoy2
Forum Newbie
Posts: 19
Joined: Fri Oct 17, 2008 9:31 am

When did classes arrive to php?

Post by JohnBoy2 »

Sorry for such a simple question, but I am brand new to php. I'm trying to implement a client package in php, and I think it would benefit from the notion of classes.

My question is: when was the concept of classes introduced to php? If classes are a relatively new thing in php, then I may choose to implement without them, as I want my software to be as widely usable as possible.

(I tried Googling, but had no luck.)

Thanks in advance to all who reply,

John
User avatar
papa
Forum Regular
Posts: 958
Joined: Wed Aug 27, 2008 3:36 am
Location: Sweden/Sthlm

Re: When did classes arrive to php?

Post by papa »

PHP 4 was released 2000 and have support for oop so you should not have to worry too much.
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: When did classes arrive to php?

Post by onion2k »

If you want it to be usable by everyone, write it in PHP4.

If you want it to be good, write it in PHP5.
raysleith
Forum Newbie
Posts: 10
Joined: Sat Oct 04, 2008 10:26 am

Re: When did classes arrive to php?

Post by raysleith »

onion2k wrote:If you want it to be usable by everyone, write it in PHP4.

If you want it to be good, write it in PHP5.
Is PHP4 better to be usable by other than PHP5?
why not just using the most new one (PHP5) ?
JohnBoy2
Forum Newbie
Posts: 19
Joined: Fri Oct 17, 2008 9:31 am

Re: When did classes arrive to php?

Post by JohnBoy2 »

Thanks very much - that's exactly the kind of info. I was hoping to obtain.

By writing in more modern versions of a platform, you are likely to utilize features that are not present in earlier versions. This is generally not a problem if you're developing a standard application, but can be a problem when writing "meta-apps". In my case, I am writing a php client that is to be used by other developers, and this client may very well need to be integrated into an older project that may not support classes, for example.

I've decided to write two versions for php - one that implements using a class, and one that uses simple global vars. and functions.

Thanks all,

John
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: When did classes arrive to php?

Post by onion2k »

No library should ever pollute the global scope. Even one for PHP4.
JohnBoy2
Forum Newbie
Posts: 19
Joined: Fri Oct 17, 2008 9:31 am

Re: When did classes arrive to php?

Post by JohnBoy2 »

No library should ever pollute the global scope. Even one for PHP4.
I sure won't argue with that. But alas, what are my options, if I can't use classes? Static function var.'s?

John
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: When did classes arrive to php?

Post by onion2k »

It depends what you're writing. Only you can tell.
JohnBoy2
Forum Newbie
Posts: 19
Joined: Fri Oct 17, 2008 9:31 am

Re: When did classes arrive to php?

Post by JohnBoy2 »

First of all, a big thanks to all of you for helping me arrive at a decision. I've implemented two versions that ought to work for most scenarios.

First up, here is the class version, which I expect will by far be the most popular:

Code: Select all

<?php
 
/* 
 * This is the TimeChannels Artificial System Clock implementation class for PHP.
 * Everywhere in your application codebase that obtains the date/time directly, replace with a call
 * to the getSystemDate() function in this class.
 * 
 * For simple unit-testing, you can call setToStaticTestState() and pass it a specific date-time value.
 * 
 * For system, integration, acpt testing, call setToTestState() and pass it a specific channel id you have setup in
 * the TimeChannels.com control panel.
 * 
 * Return to normal time by calling setToProductionState()
 */
 
class TimeChannels {
  private static $tcURL = "http://www.timechannels.com/GetChannel";
  private static $tcURLms = "http://www.timechannels.com/GetChannelMS";
  private static $tcAscState = "TimeChannels.state.Production";
  private static $tcChannel = "0";
  private static $tcAscDateTime = null;
  private static $tcServiceURL = "http://www.timechannels.com/GetChannel";
  private static $tcMillisecondMode = "false";
 
  public static function setToProductionState() {
    self::$tcAscState = "TimeChannels.state.Production";
  }
 
  public static function setToStaticTestState($aDateTimeValue) {
    self::$tcAscState = "TimeChannels.state.TestDate";
    self::$tcAscDateTime = $aDateTimeValue;
  }
 
  public static function setToTestState($aChannel) {
    self::$tcAscState = "TimeChannels.state.TestChannel";
    self::$tcChannel = $aChannel;
  }
 
  public static function setToMillisecondMode() {
    self::$tcMillisecondMode = "true";
    self::$tcServiceURL = self::$tcURLms;
  }
 
  public static function setToStandardMode() {
    self::$tcMillisecondMode = "false";
    self::$tcServiceURL = self::$tcURL;
  }
 
  public static function getSystemDate() {
    if (self::$tcAscState == "TimeChannels.state.Production") return mktime();
 
    if (self::$tcAscState == "TimeChannels.state.TestDate") return self::$tcAscDateTime;
 
    if (self::$tcAscState == "TimeChannels.state.TestChannel") return self::getChannelFromTimeChannelsService(self::$tcChannel);
 
    return mktime();  
  }
 
  private static function getHTTPContent( $url ) {
    $options = array( 'http' => array(
        'user_agent'    => 'timechannelsclient',    // who am i
        'max_redirects' => 10,          // stop after 10 redirects
        'timeout'       => 120,         // timeout on response
    ) );
    $context = stream_context_create($options);
    $page = @file_get_contents($url, false, $context);
 
    $result = array();
    if ($page != false)
      $result['content'] = $page;
    else if (!isset($http_response_header))
      return null;    // Bad url, timeout
 
    $result['header'] = $http_response_header;
 
    $nLines = count($http_response_header);
    for ($i = $nLines-1; $i >= 0; $i--) {
      $line = $http_response_header[$i];
      if (strncasecmp("HTTP", $line, 4) == 0) {
        $response = explode(' ', $line);
        $result['http_code'] = $response[1];
        break;
      }
    }
    return $result;
  }
 
  private static function getChannelFromTimeChannelsService($aChannel) {
 
    $url = self::$tcServiceURL . "?channel=" . $aChannel;
    $result = self::getHTTPContent($url);
 
    if ($result == null) return mktime();
    if ($result['http_code'] != 200) return mktime();
 
    $channelValue = $result['content'];
 
    if (self::$tcMillisecondMode == "true") {
      $retVal = (1 * $channelValue) / 1000;
    }
    else {
      $year = 1 * substr($channelValue, 0, 4);
        //echo "year: $year <br>";
      $month = 1 * substr($channelValue, 5, 2);
        //echo "month: $month <br>";
      $day = 1* substr($channelValue, 8, 2);
        //echo "day: $day <br>";
      $hour = 1 * substr($channelValue, 11, 2);
        //echo "hour: $hour <br>";
      $minute = 1 * substr($channelValue, 14, 2);
        //echo "minute: $minute <br>";
      $ampm = substr($channelValue, 17, 2);
        //echo "ampm: $ampm <br>";
 
      if ($ampm == "PM") $hour += 12;
 
      $retVal = mktime($hour, $minute, 0, $month, $day, $year);
    }
 
    return $retVal;
  }
 
}
 
?>
 
You can see that this "client" is a bit more than a mere proxy stub to the web-service. The class implements the concept of an Artificial System Clock (ASC). There is state maintained by the class to enable developers/testers to turn the ASC on/off. Also, there is the ability to simply test locally with a supplied static date, or to point the ASC at a channel that has been setup at http://www.TimeChannels.com. There are also important safety features which allow the system to be used even if the web service is down.

The question is: how best to implement this for older (pre-4.0, right?) versions of PHP, specifically versions that don't allow classes, or the use of static vars. (Or anything else you can see in there that might pose a problem for legacy php apps...)

For the time being, I have written a naive approach to this using global vars, but I would like to hear if there are superior options.

Thanks,

John
Last edited by Benjamin on Thu Jun 11, 2009 7:20 pm, edited 1 time in total.
Reason: Changed code type from text to php.
JohnBoy2
Forum Newbie
Posts: 19
Joined: Fri Oct 17, 2008 9:31 am

Re: When did classes arrive to php?

Post by JohnBoy2 »

Here is the code for what I am calling the "legacy" version of the php client:

Code: Select all

<?php
 
/* This is a rudimentary implementation of the TimeChannels Artificial System Clock, intended for use with very old
 * php versions which don't support classes.  PHP 4+ users should use the class-based TimeChannels.php source.
 *
 * Please note the following global vars - do not overwrite these.  If there is a conflict with other global vars in
 * your application, these can be renamed, but of course make sure all references in this file match.
 *
 * Everywhere in your application codebase that obtains the date/time directly, replace with a call
 * to the getSystemDate() function in this class.
 * 
 * For simple unit-testing, you can call setToStaticTestState() and pass it a specific date-time value.
 * 
 * For system, integration, acpt testing, call setToTestState() and pass it a specific channel id you have setup in
 * the TimeChannels.com control panel.
 * 
 * Return to normal time by calling setToProductionState()
 */
 
$tcURL = "http://www.timechannels.com/GetChannel";
$tcURLms = "http://www.timechannels.com/GetChannelMS";
$tcAscState = "TimeChannels.state.Production";
$tcChannel = "0";
$tcAscDateTime = null;
$tcServiceURL = $tcURL;
$tcMillisecondMode = "false";
 
 
function setToProductionState() {
  global $tcAscState;
  $tcAscState = "TimeChannels.state.Production";
}
 
 
function setToStaticTestState($aDateTimeValue) {
  global $tcAscState, $tcAscDateTime;
  $tcAscState = "TimeChannels.state.TestDate";
  $tcAscDateTime = $aDateTimeValue;
}
 
 
function setToTestState($aChannel) {
  global $tcAscState, $tcChannel;
  $tcAscState = "TimeChannels.state.TestChannel";
  $tcChannel = $aChannel;
}
 
 
function setToMillisecondMode() {
  global $tcMillisecondMode, $tcServiceURL, $tcURLms;
  $tcMillisecondMode = "true";
  $tcServiceURL = $tcURLms;
}
 
 
function setToStandardMode() {
  global $tcMillisecondMode, $tcServiceURL, $tcURL;
  $tcMillisecondMode = "false";
  $tcServiceURL = $tcURL;
}
 
 
function getSystemDate() {
  global $tcAscState, $tcAscDateTime, $tcChannel;
 
  if ($tcAscState == "TimeChannels.state.Production") return mktime();
 
  if ($tcAscState == "TimeChannels.state.TestDate") return $tcAscDateTime;
 
  if ($tcAscState == "TimeChannels.state.TestChannel") return getChannelFromTimeChannelsService($tcChannel);
 
  return mktime();  
}
 
 
function getHTTPContent( $url ) {
  $options = array( 'http' => array(
      'user_agent'    => 'spider',    // who am i
      'max_redirects' => 10,          // stop after 10 redirects
      'timeout'       => 120,         // timeout on response
  ) );
  $context = stream_context_create($options);
  $page = @file_get_contents($url, false, $context);
 
  $result = array();
  if ($page != false)
    $result['content'] = $page;
  else if (!isset($http_response_header))
    return null;    // Bad url, timeout
 
  $result['header'] = $http_response_header;
 
  $nLines = count($http_response_header);
  for ($i = $nLines-1; $i >= 0; $i--) {
    $line = $http_response_header[$i];
    if (strncasecmp("HTTP", $line, 4) == 0) {
      $response = explode(' ', $line);
      $result['http_code'] = $response[1];
      break;
    }
  }
  return $result;
}
 
 
function getChannelFromTimeChannelsService($aChannel) {
  global $tcServiceURL, $tcMillisecondMode;
 
  $url = $tcServiceURL . "?channel=" . $aChannel;
  $result = getHTTPContent($url);
 
  if ($result == null) return mktime();
  if ($result['http_code'] != 200) return mktime();
 
  $channelValue = $result['content'];
 
  if ($tcMillisecondMode == "true") {
    $retVal = (1 * $channelValue) / 1000;
  }
  else {
    $year = 1 * substr($channelValue, 0, 4);
      //echo "year: $year <br>";
    $month = 1 * substr($channelValue, 5, 2);
      //echo "month: $month <br>";
    $day = 1* substr($channelValue, 8, 2);
      //echo "day: $day <br>";
    $hour = 1 * substr($channelValue, 11, 2);
      //echo "hour: $hour <br>";
    $minute = 1 * substr($channelValue, 14, 2);
      //echo "minute: $minute <br>";
    $ampm = substr($channelValue, 17, 2);
      //echo "ampm: $ampm <br>";
 
    if ($ampm == "PM") $hour += 12;
 
    $retVal = mktime($hour, $minute, 0, $month, $day, $year);
  }
 
  return $retVal;
 
}
 
 
?>
 
So you can see that it's pretty much a straight translation of the OO version of the client, but all the static class variables have been replaced with globals.

Thanks for looking, and I would be grateful for any/all feedback, especially if there's a better way to do this, for versions of php that do not support classes.

Thanks,

John
Last edited by Benjamin on Thu Jun 11, 2009 7:21 pm, edited 1 time in total.
Reason: Changed code type from text to php.
JohnBoy2
Forum Newbie
Posts: 19
Joined: Fri Oct 17, 2008 9:31 am

Re: When did classes arrive to php?

Post by JohnBoy2 »

Has anyone figure out a better way than the global var's I used to deal with "Legacy" PHP versions?

Just curious...

John
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: When did classes arrive to php?

Post by Weirdan »

The question is: how best to implement this for older (pre-4.0, right?) versions of PHP,
Simple and comprehensive answer: you don't have to. PHP3 is virtually non-existing today, hosting offers are scarce, no new software is developed for this ancient version. It's long dead. Official support has been ended even for PHP4 already.

So you'd better maintain one version, written with PHP4 compatibility in mind (code for PHP4 is mostly compatible with PHP5, but PHP3 and PHP4 are quite different).
Post Reply