Jump to content

Upgrading from PHP 4 to PHP 5.4 Problems


0tter

Recommended Posts

Hi there, I wondered if there was anyone out there who could help.

 

I did some PHP coding some years ago for a site, the site is hosted on oneandone and a couple of months back we went through the traumatic exercise of updating the site to the version 5 MySQL and now I'm going through a similar exercise to upgrade from version 4 to version 5.4 PHP.

 

Now I know I should have done this ages ago but it's not really my site and I've just accepted the onerous responsibility of doing this upgrade - despite forgetting just about everything I know about PHP. Hey I've got to that age now :-)

 

Basically though switching over to PHP 5.4 on oneandone is a doddle but once you do this then no-one can log in.

 

I'm trying to switch on error reporting but that's not being very successful, but I have found a chink of light in that once one requests a new password then it still does not work, but the reasoning for it not working - it seems to me - is that it's not finding the username in the user database. So either it's not passing the username or its somehow just not finding the username in the database.

 

This is the questionable function code:

 

function notify_password($username, $password)
// notify the user that their password has been changed
{
    if (!($conn = db_connect()))
      return false;
    $result = mysql_query("select email from user
                            where username='$username'");
    if (!$result)
    {
      return false;  // not changed
    }
    else if (mysql_num_rows($result)==0)
    {
      return false; // username not in db
    }
    else
    {
      $email = mysql_result($result, 0, 'email');
      $from = "From: test@test.com \r\n";
      $mesg = "Your Test.com password has been changed to $password \r\n"
              ."Please change it next time you log in. \r\n";
     
     
      if (mail($email, 'Test.com login information', $mesg, $from))
        return true;     
      else
        return false;    
    }
}

 

 

I reckon it fails at the:

 

$result = mysql_query("select email from user
                            where username='$username'");
    if (!$result)
    {
      return false;  // not changed

 

 

bit.

 

I could be wrong but I changed the "return false" to "return true" for this bit and it seemed to make things better, well at least it thought it was working.

 

Any help would be very much appreciated but please be gentle as I'm not really a PHP freak, I'm more a PHP twiddler.

 

Cheers,

 

Bill
 

Edited by 0tter
Link to comment
Share on other sites

the bit of code you pinpointed - if (!$result) ... means that the query failed due to an error. for debugging purposes, echo mysql_error() to find out why it failed.

 

Aha, that sounds like good advice, I'll give that a go now.

 

Cheers

Link to comment
Share on other sites

Nothing in that code is different between php4 and php5, I would like to see where this function is actually called.

It's called from forgot_password.php

 

This code is:

 

 

<link href="../css/secure_page.css" rel="stylesheet" type="text/css">

<?php

  require_once("bookmark_fns.php");

  do_html_header("Resetting password");

  //creating short variable name

  $username = $HTTP_POST_VARS['username'];

  if ($password=reset_password($username))

  {

    if (notify_password($username, $password))

     {

   ?>

      Your password has been emailed to your email address.

      <br>

      We recommend you change it to something memorable as soon as you can.

      <br>

      <?php

   display_login_form();

   do_html_footer();

   }

 else

   {

      ?>

      Your password could not be emailed to you.

      <br>

      Try again later

      <br>

      <?php

    display_forgot_form();

      do_html_footer();

   }

  }

  else

      {

      ?>

      Your password could not be emailed to you.

      <br>

      Try again later

      <br>

      <?php

    display_forgot_form();

       do_html_footer();

 }

//   do_html_url('login.php', 'Login');

//  do_html_footer();

?>

Edited by 0tter
Link to comment
Share on other sites

Aha, that sounds like good advice, I'll give that a go now.

 

Cheers

I added it to the code as below, but it's not spilling the beans, am I doing something wrong with it?

 

function notify_password($username, $password)

// notify the user that their password has been changed

{

    if (!($conn = db_connect()))

      echo mysql_error(); 

//      return false;

    $result = mysql_query("select email from user

                            where username='$username'");

    if (!$result)

    {  

      echo mysql_error();

//      return false;  // not changed

    }

    else if (mysql_num_rows($result)==0)

    {

      echo mysql_error();

//   return false; // username not in db

    }

    else

    {

      $email = mysql_result($result, 0, 'email');

      $from = "From: support@TheLitmusTest.com \r\n";

      $mesg = "Your TheLitmusTest.com password has been changed to $password \r\n"

              ."Please change it next time you log in. \r\n";

     

     

      if (mail($email, 'TheLitmusTest.com login information', $mesg, $from))

        return true;     

      else

     echo mysql_error();

        return false;    

    }

}

Link to comment
Share on other sites

your code/server may be buffering output then redirecting, thereby discarding any output. add a die; statement after the echo mysql_error(); to stop the code from running at that point.

Doing it now...

 

Speak now or else it's the thumbscrews....

Link to comment
Share on other sites

Well I tried it out:

 

 else if (mysql_num_rows($result)==0)
    {
      echo mysql_error();
   die;
//   return false; // username not in db
    }
    else

 

And it did well and truly stop at this point, so this seems to be the cause of concern, but beans were not spilled and it just came up with a blank.

 

Actually I tried it in a few spots too - just in case - and added some other echo statements around it just to make sure it was getting to this point but it was all to no avail.

 

I'm not having much luck today am I, I did however think that was a brilliant idea and we were getting closer to the solution but not being able to get an error is not much help.

 

Any more suggestions would be very very welcome.

Link to comment
Share on other sites

register_long_arrays deprecated in 5.3 and removed in 5.4.

$HTTP_POST_VARS['username']
// will need to be
$_POST['username']

And everything else like that.  This will probably be a major undertaking.

 

You can google and find a sed, perl, bash or replace command that should work.  Just make sure to backup all the files first.

Edited by AbraCadaver
Link to comment
Share on other sites

when a query doesn't match any rows (the code branch in post #9) it isn't an error and mysql_error() won't contain anything.

 

if that's the code branch that is returning the false value, then the username is likely empty. see AbraCadaver's post above for the most likely reason why.

 

if you set php's error_reporting to E_ALL and display_errors to ON, you will get php to help you by pointing out things like variables that don't exist.

Link to comment
Share on other sites

register_long_arrays deprecated in 5.3 and removed in 5.4.

$HTTP_POST_VARS['username']
// will need to be
$_POST['username']

And everything else like that.  This will probably be a major undertaking.

 

You can google and find a sed, perl, bash or replace command that should work.  Just make sure to backup all the files first.

I was worried that it was going to be something like this.

 

There's a lot of code on the site, do you reckon that there's going to be anymore like this?

 

Surely looking at this it's just a search for $HTTP_POST_VARS and replace with $_POST

 

I doubt it could be just that easy...

 

Cheers, you've been a great help too.

Link to comment
Share on other sites

when a query doesn't match any rows (the code branch in post #9) it isn't an error and mysql_error() won't contain anything.

 

if that's the code branch that is returning the false value, then the username is likely empty. see AbraCadaver's post above for the most likely reason why.

 

if you set php's error_reporting to E_ALL and display_errors to ON, you will get php to help you by pointing out things like variables that don't exist.

Funnily enough this is what I tried first when I was trying to get the error reporting to work.

 

It was completely fruitless and when your error reporting suggestion was posted then that's where I thought the solution would lie.

 

Still onward and upward, it might be a bit of a job now but I'm one step further to getting it all sorted out.

 

I'll carry on posting here with all you every so helpful folk and see if I can get it all worked out.

 

Cheers you've been uber-helpful.

 

Bill

Link to comment
Share on other sites

If you're on linux and have made a backup copy of your html directory, then try something like this in the main html directory:

find . -name '*.php' -type f -exec sed -i 's/\$HTTP_POST_VARS/\$_POST/g' {} \;

You'll also have to look for $HTTP_GET_VARS and maybe COOKIE and SESSION and SERVER, I can't remember.

Link to comment
Share on other sites

If you're on linux and have made a backup copy of your html directory, then try something like this in the main html directory:

find . -name '*.php' -type f -exec sed -i 's/\$HTTP_POST_VARS/\$_POST/g' {} \;

You'll also have to look for $HTTP_GET_VARS and maybe COOKIE and SESSION and SERVER, I can't remember.

Crikey all of those too.

 

I'll have to get some coding done this weekend - if only I didn't have a three year old to look after on Saturday and Sunday.

 

I'll see what I can get done tonight.

 

Cheers,

 

Bill

Link to comment
Share on other sites

If you're on linux and have made a backup copy of your html directory, then try something like this in the main html directory:

find . -name '*.php' -type f -exec sed -i 's/\$HTTP_POST_VARS/\$_POST/g' {} \;

You'll also have to look for $HTTP_GET_VARS and maybe COOKIE and SESSION and SERVER, I can't remember.

 

 

Well I'm getting somewhere, the lost password function works but logging in only works the first time one tries to do it, the second login attempt will not let you login - darn it.

 

I tried doing search and replaces on:

 

Search                                  Replace

 

$HTTP_GET_VARS             $_GET

 

$HTTP_POST_VARS           $_POST

 

$HTTP_COOKIE_VARS       $_COOKIE

 

$HTTP_SESSION_VARS     $_SESSION

 

$HTTP_SERVER_VARS       $_SERVER

 

You reckon that's all of them, or might there be one or two that I'm missing.

 

Do you think that a global search and replace was wise and am I likely to be opening a large can of squiggly worms.

 

Thanks... apologies if you don't get a reply pronto but I'm on child minding duties for most of the weekend.

 

Cheers,

 

Bill

Link to comment
Share on other sites

There may be other problems.  Har d to tell without code. I checked php.net and I couldn't find a list of these long arrays.  Do you have files that are included that don't have the php extension?  Either html or inf, cfg, etc..?  If so, then you need to adjust the find to replace in those files as well.

Edited by AbraCadaver
Link to comment
Share on other sites

Aha, I've managed to find some time to get this sorted and.....

 

My host oneandone offers two flavours of PHP version 5 to upgrade to: 5.2 and 5.4. I had been working with 5.4 but I accidently flicked on 5.2 today and I found that I was actually getting some error messages for a change. Why I just do not know, but they've proved mega helpful so far, I was really operating in the dark without them.

 

Anyway I've got through a bundle of errors and I'm a bit stuck on this one now:

 

Warning: extract() [function.extract]: First argument should be an array in /homepages/11/d101038731/htdocs/website/phpscripts/terms_and_conditions_frameset.php on line 20

 

Line 20 being the last line of this code..... could it be the mysql_fetch_array($result); is the problem....?

 

 

$query = "SELECT familyid, email FROM user WHERE username='$username'";   
    $result = mysql_query($query) 
    or die ("Couldn't execute query.");
 $row = mysql_fetch_array($result);
 extract($row);

Link to comment
Share on other sites

for that specific code, it means that the query matched no rows.

 

the code is checking if the query execuited (the or die(...) logic), but is not testing if the query matched any rows before trying to fetch and use a row from a result set that doesn't have any rows.

 

ideally, the logic should test if mysql_num_rows($result) > 0 to see if the query returnd any rows before attempting to fetch and use any of the data in the result set and if that test if not true, output an appropiate message (i.e. username not found) and skip over any logic that is dependent on the query matching a username.

Link to comment
Share on other sites

Thanks for the suggestion, I'll give that a go and see if it sheds any light on the solution.

 

Thing is though that this all worked fine in PHP 4 and I've not changed a thing to stop it working in 5.2.

 

Great suggestion though, I'll deffo give it a go.

 

Cheers

 

Bill

Link to comment
Share on other sites

Thing is though that this all worked fine in PHP 4

 

 

 

the current error was ALWAYS occuring at the extract statement when the query didn't return any rows, but the reporting or display of the final step, the error message, was being hidden due to the error_reporting and/or display_errors settings. the extract statement producing that error when there's nothing to extract doesn't have anything to do with the php version.

 

saidly, php actively promoted hiding errors as a way of letting non-coders produce code that 'worked' without it actually being good code. the time someone saved when they were writting this script, in not checking if the query returned a row or not, is being spent by you now in just finding out why the code is producing the errors.

 

for the current error message, if you ignore the error message, does the code actually do what you expect when the username isn't found in the database table? the extract statement is failing and it is not creating the $familyid and $email variables. does the code take an expected execution path and produce the expected result when those variables don't exist?

 

the suggestion i gave to test if the query actually matched a row in the database before attempting to use that data and to output a message when there is no matching data will cause the code to take an expected execuition path regardless of if the query did or didn't match the username. i.e. the code will always do something and tell you what it is that it did. there won't be any blank pages or guessing about what the code is doing. this is how good code is written and how this code you are fighting with should have been written in the first place.

Link to comment
Share on other sites

Aha so it always occurring.

 

I was wondering about that, the thing is having been away from PHP for years now this is all a new mystical art to me again. The problem I have getting my head around is that if I switch to 4 then there's no error reporting (as you kindly pointed out) then switch to 5.2 and hey presto there it is, but behold when I switch to 5.4 it disappears again, that's why all a bit confused.

 

Thing is too, I copied a lot and I mean a lot of the code from a lofty book, to find out now that it's all flawed is quite an eye-opener to me. I have the book in storage somewhere and if I could find out what it was then it might be just a matter of finding the latest edition to find out what the code might be now - any suggestions on the back of a postcard please.

 

I'm off to the beach with the little un today, I actually had a really bad nights sleep last night waking up thinking of coding, that's how much it's got to me. I really could do without the child minding but I've got to do it and the PHP 4 is switched off next week so I'm getting very uncomfortable with the whole situation.

 

Thanks again for all your help.

 

Cheers,

 

Bill

Link to comment
Share on other sites

an introductory programming book, tutorial, class,... is only going to show the basics and maybe mention the need for security and application level error checking/reporting/recovery logic. it should really be the other way around. start by teaching the need for security and checking for problems at each step that can fail, then teach how to write logic that does something.

 

the threads/problems you have been posting are due to two things -

 

1) old depreciated/superseded features (most of which were depreciated/superseded in the years 2001/2002 and since then there have been very few changes that are not backwardly compatible for most code) that must to be updated to current standards to even work on current or near future php versions. there are migration sections in the php.net documentation that list what has actually been changed in each major php version. reading these might help you. they are in the php.net documentation appendix and can be found by searching for "php migration". the php change logs (one for php4 and one for php5) also have sections listing the actual changes for each version along with bugs that were fixed.

 

2) minimalistic code that just barely 'works' when everything is perfect, but vomits when the least little thing isn't right and doesn't tell you when, where, or what is wrong that caused it to vomit. writing code that doesn't produce fatal-errors/warnings/notices each time it runs takes time to write. even if the error messages are hidden due to php settings, php is still detecting all these errors when the code runs. the error_reporting and display_errors/log_errors settings only determine what happens when an error is detected. is it reported and if it is reported, is the message displayed or logged? a lot of live servers have php's error logging turned on and is not uncommon to see GIGABYTE size error log files that eventually take up all the free disk allotment due to php code that produces 100's of warnings/notices each time it runs. also, since hackers can easily cause minimalistic code to produce errors by feeding it data that isn't prefect, if display_errors are turned on, this gives hackers important information about the directory structure and account names and if using things like mysql_error() in your code, being able to trigger database errors  exposes the database hostname and username to the hacker.

 

for item #1, you must fix this things for the code to run. for item #2, time to pay the Piper.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.