We help IT Professionals succeed at work.

Updating website page to PHP 7

Wanda Marston
on
Recently, I updated my server from PHP 5 to PHP 7 and now I need to update my website so that the pages work properly in PHP 7.

At this point I am working on my users LOGIN page.


BASIC LOGIN PAGE SCRIPT
<?php

// Require the configuration before any PHP code as the configuration controls error reporting:
require ('../yarnextrasJu19/includes/config.inc.php');
//The config file also starts the session.

// Require the database connection:
require (MYSQL);

// Require the database connection:
// If it's a POST request, handle the login attempt:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	require ('../XXXXXXXXX/includes/login.inc.php');
}
?>
<!doctype html>
<head>
<title>Login</title>
</head>
<body>
<!-- Page Wrapper -->
<div id="page-wrapper">

<div class="logo">
  
<div id="description">

    <?php
 	if (isset($_SESSION['user_id'])) {
		// Show basic user options:

		$q = "SELECT id, username, email FROM users WHERE  id={$_SESSION['user_id']}";

		$r = mysqli_query($db, $q);

		if (mysqli_num_rows($r) > 0) {

			while ($row = mysqli_fetch_array($r, MYSQLI_NUM)) {
				$username = $row[1];
				$email = $row[2];

				// Display the username and heading
				echo "<p><h2a>Hello $username!</p>
		<p><h2a>Your Current Email: $row[2]</h2a></p><br><br />";
		}
}
// Show basic user options:

echo '<div align="center"><h3a>Manage Your Account </h3a>
    
		<p><a href="PostANoticeYE.php" title="Post A Notice">Post A Notice</a><br />
		<a href="MemberNoticesYE.php" title="MemberNotices">Member Notices</a><br />
		<a href="EditNoticesYE.php" title="Edit Notices">Edit My Notices</a><br />
		<a href="MemberProfileYE.php" title="Member Profile">Member Profile / Change Email</a><br />
		<a href="CancelRenewYE.php" title="Cancel or Renew">Cancel Membership</a><br />
    	<a href="ResetPassword.php" title="Change Your Password">Change Password</a></p>
 </center>';
           				
} else { // Show the login form:

// Show the login form:
	require ('../XXXXX/includes/login_form.inc.php');
}
?>
</div> 
 <!-- Footer -->
</div> 
</body>
</html>

Open in new window



LOGIN FORM CODE
<?php

// Create an empty error array if it doesn't already exist:
if (!isset($login_errors)) $login_errors = array();

// Need the form functions script, which defines create_form_input():
require_once ('./includes/form_functions.inc.php');
?>

<form action="Login.php" method="post" accept-charset="utf-8">

<h2>LOGIN</h2>
	
<?php if (array_key_exists('login', $login_errors)) {
echo '<span class="error">' . $login_errors['login'] . '</span>'; }?></p>

<p><label for="email" class="SmallHeading"><strong>Email Address</strong></label>
<p><?php create_form_input('email', 'text', $login_errors); ?></p>

<p><label for="pass2" class="SmallHeading"><strong>Password</strong></label></p>
<p><a href="ForgotPassword.php"><h2>Forgot Your Password?</h2></a></p>
<p><?php create_form_input('pass', 'password', $login_errors); ?></p>
      
<button class="button" style="vertical-align:left"><span>Login &rarr;</span></button><br />
<br />
</form>

Open in new window


FORM FUNCTIONS CODE

<?php

// Defines any functions required by the various forms.

// This function generates a form INPUT or TEXTAREA tag.
// It takes three arguments:
// - The name to be given to the element.
// - The type of element (text, password, textarea).
// - An array of errors.

function create_form_input($name, $type, $errors) {
	
	// Assume no value already exists:
	$value = false;

	// Check for a value in POST:
	if (isset($_POST[$name])) $value = $_POST[$name];
	
	// Strip slashes if Magic Quotes is enabled:
	if ($value && get_magic_quotes_gpc()) $value = stripslashes($value);

// Conditional to determine what kind of element to create
	
	if (($type == 'text') || ($type == 'password') || ($type == 'checkbox')) { // Create text or password inputs.
		
		// Start creating the input:
		echo '<input type="' . $type . '" name="' . $name . '" id="' . $name . '" size=50"';
		
		// Add the value to the input:
		if ($value) echo ' value="' . htmlspecialchars($value) . '"';

		// Check for an error:
		if (array_key_exists($name, $errors)) {
			echo 'class="error" /> <span class="error">' . $errors[$name] . '</span>';
		} else {
			echo ' />';		
		}
		
	} elseif ($type == 'textarea') { // Create a TEXTAREA.
		
		// Display the error first: 
		if (array_key_exists($name, $errors)) echo ' <span class="error">' . $errors[$name] . '</span>';

		// Start creating the textarea:
		echo '<textarea name="' . $name . '" id="' . $name . '" rows="5" cols="43"';
		
		// Add the error class, if applicable:
		if (array_key_exists($name, $errors)) {
			echo ' class="error">';
		} else {
			echo '>';		
		}
		
		// Add the value to the textarea:
		if ($value) echo $value;

		// Complete the textarea:
		echo '</textarea>';
		
} elseif ($type == 'checkbox') { // Create a CHECKBOX.

		// Start creating the input:
		echo '<input type="' . $type . '" name="' . $name . '" value="';

       
	   // Add the value to the input:
		if ($value) echo ' value="' . htmlspecialchars($value) . '"';
		
		
		// Display the error:
		if (array_key_exists($name, $errors)) {
			
			echo ' />';		
		}
		
	} // End of primary IF-ELSE.

}// End of the create_form_input() function.

// Omit the closing PHP tag to avoid 'headers already sent' errors!

Open in new window

Comment
Watch Question

Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hey Wanda,

First off - good choice. Updating can be a pain, but it needs doing and will help you code run better.

Now, the good news is that sometimes, upgrading your code to PHP7 doesn't actually need anything doing. If you're not using any deprecated functions, then you may get away without doing anything. The simplest way to check your code is to turn on full error_reporting and run your code. Add the following to the very start of your pages:

error_reporting(E_ALL);
ini_set('display_errors', 1);

Open in new window

This will now show you any errors as well as warnings (such as deprecated warnings etc).

There are tools available that can analyse your code (code sniffers etc) and sometimes even try and fix them. They might be worth considering if you have a large codebase, but if you have just a few files, manually running and fixing may just be easier and quicker (and you'll learn along the way)

Glancing over your code, and I can't actually see anything that would break under PHP7.

Have you found something in your code that doesn't work as it is?
Wanda MarstonCreative Director

Author

Commented:
Thanks for your suggestion regarding the error reporting. It makes sense to do this.

These are the two errors I am currently receiving at the top of my LOGIN page – (I have purposely X'd out some of it for posting to this page)
============

Warning: session_start(): open(/var/php_sessions/sess_rd7ri71f3air9dbl1k7fsuaajkr8vf8j, O_RDWR) failed: No such file or directory (2) in /hermes/bosnacweb04/bosnacweb04aj/b717/nf.XXXXXXXXXX/public_html/XXXXXX.com/includes/config.inc.php on line 30

Warning: session_start(): Failed to read session data: files (path: /var/php_sessions) in /hermes/bosnacweb04/bosnacweb04aj/b717/nf.XXXXXXXXXX/public_html/XXXXXXXX.com/includes/config.inc.php on line 30

Following is the code on the config.inc.php page

<?php # XXXXX - config.inc.php for

// Flag variable for site status:
define('LIVE', TRUE);

// Admin contact address:
define('EMAIL', 'help@yXXXXXX.com');

define ('BASE_URI','/home/users/web/b717/nf.XXXXXX/public_html/XXXXXXXX.com/');

// Site URL (base for all redirections):
define('BASE_URL', 'www.XXXXXX.com/');

// Location of the MySQL connection script:
define('MYSQL', BASE_URI . 'mysqli.inc.php');

///create a session
if (!isset($_SESSION)) {
 session_start();
}
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hmmm. Not seen that warning before, so I'm not entirely sure what's going on.

It's difficult to know whether or not this warning existed before switching to PHP7, because you didn't have error_reporting on, so the warning would have been hidden by default.

Looking at the error and it seems to indicate that the folder that PHP expects to save session data to doesn't exist. Try running a quick phpinfo and then search for session.save_path. You can run the phpinfo by creating a simple file containing just the folliwing:

<?php
phpinfo();

Open in new window

Save that file on your server and then browse to it. It will give you a lot of info about your PHP installation. Look for the session.save_path setting and see what that says. You may need to speak to you host and ask them if that folder exists and has the correct permission (i.e it's writable).

If you have the option of switching PHP version on your server (most hosts offer this through a control panel), it might be worth seeing what the settings says when running PHP7 and then seeing what it says when running PHP5 ... each version uses it's own PHP config, so there could be a discrepency between the 2)
David FavorFractional CTO
Distinguished Expert 2019

Commented:
You said, "Recently, I updated my server from PHP 5 to PHP 7 and now I need to update my website so that the pages work properly in PHP 7."

1) Be sure you upgrade to latest stable PHP-7, which PHP-7.3.6.1 is latest today.

2) No matter how good you are, trying to fix PHP by hand, to change versions is complex, so better to use the tool everyone uses to automate the upgrade process.

https://github.com/PHPCompatibility/PHPCompatibility is where this tool lives.
David FavorFractional CTO
Distinguished Expert 2019

Commented:
Use phpcs to find code to fix + phpcbf to mechanically fix many problems.

Run example, on a 16x core machine...

time nice -19 phpcs -d xdebug.show_exception_trace=0 -p --parallel=16 --standard=PHPCompatibility \
               --encoding=utf-8 --extensions=php,inc,lib,js,css,html --runtime-set testVersion 7.3 /cluster/sites \
               > ~/app-php-5.6-tofix.txt 2>/dev/null

Open in new window


Use multiple -d options to disable various code, which will crash or interfere with phpcs + phpcbf.

You can also setup custom ruleset files, so if you have one warning produced by 1,000,000s of files you plan on skipping for now, you can create a custom .xml ruleset file to exclude one or more tests.
Hi,

This warning started with PHP 7.1 , try to set the main directory to  CHMOD 755 .

You can test your code on your computer using Wampserver you can run both PHP versions (one at the time) using the version selector.
http://www.wampserver.com/en/

You can use xdebug tool (which is already included in wamp), this is probably the most useful tool, and this is easier to understand errors https://xdebug.org/

You can use PHPStorm https://www.jetbrains.com/phpstorm/ it have a compatibility checker, this tool can be great but not easy to use, it have some learning curve...
David FavorFractional CTO
Distinguished Expert 2019

Commented:
As lenamtl said, the PHPStorm version has a steep learning curve.

I prefer running the code on the server side + fixing every file where it lives, rather than adding an IDE into the mix.

After you make the first passes with phpcs + phpcbf, then switch over to your IDE, if required.
David FavorFractional CTO
Distinguished Expert 2019

Commented:
Best I add the steps to actually install phpcs + phpcbf, so they work as the process... to me... is complex...

If you're not running Debian/Ubuntu, how you get latest PHP-7.3 to run will be a long + time consuming task. You'll have to search for correct repositories or build from source.

#
 Setup all latest stable PPAs

LC_ALL=C.UTF-8 add-apt-repository ppa:mamarley/updates </dev/null
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/apache2 </dev/null
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php </dev/null
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/nginx-mainline </dev/null
LC_ALL=C.UTF-8 add-apt-repository ppa:isc/bind-dev </dev/null

curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash -s -- --skip-maxscale

# Install minimal requirements for phpcs + phpcbf to run, along with a few other PHP tools

apt-get install php7.3-cli php7.3-xml php7.3-mbstring php7.3-zip

# Where all PHP Comptibility code will live

cd
mkdir ~/php-code-sniffer && cd ~/php-code-sniffer

git clone https://github.com/squizlabs/PHP_CodeSniffer.git PHP_CodeSniffer.git
git clone https://github.com/wimg/PHPCompatibility.git PHPCompatibility.git

# In ~/.bashrc: PATH=$PATH:~/php-code-sniffer/PHP_CodeSniffer.git/bin
# Source ~/.bashrc again

# This should work now

which phpcs phpcbf

# Setup Coding Standard packs

phpcs -d xdebug.show_exception_trace=0 --config-set installed_paths ~/php-code-sniffer/PHPCompatibility.git
phpcs -d xdebug.show_exception_trace=0 --config-show installed_paths

# Both phpcs + phpcbf should show the following "Coding Standard" packs are set...
# Zend, PSR2, PEAR, Squiz, PSR1, MySource and PHPCompatibility

phpcs -d xdebug.show_exception_trace=0 -i
phpcbf -d xdebug.show_exception_trace=0 -i

# Set --parallel=your-number-of-cores

nice -19 phpcs -d xdebug.show_exception_trace=0 -p --parallel=16 --standard=PHPCompatibility \
     --encoding=utf-8 --extensions=php,inc,lib,js,css,html --runtime-set testVersion 7.3 \
     /path-to-files-to-check > ~/app-php-5.6-tofix.txt 2>/dev/null

Open in new window

Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
All of these suggestions are great ... if you're a more advanced user, that has SSH access to your Server and you know how to install software on your Linux Environment.

The truth is that msot people don't. On many shared hosting accounts, SSH simply isn't allowed, or if it is, it's locked down in a tight chrooted environment, so you probably can't install software anyway. And even if you can SSH, most people don't ever need to concern themselves with logging into the terminal.

If the app is relatively small and simple, turning on error reporting and manually fixing things (there's not usually that much) is often the quickest and easiest way, so I would suggest you stick with that approach
Wanda MarstonCreative Director

Author

Commented:
Thanks for all the suggestions.

I have used Wampserver in the past and used to have a server on my Mac and used Terminal and a few other things like that. THEN when I had to upgrade my mac, I somehow lose files and there were all kinds of problems so I just started using my web hosts server. Sometimes I nest a website I am developing inside one that is already live. I would prefer not to go back to that kind of web developing.

My hosting company has a Debian platform. I am now on PHP Version - 7.3.2.

When I checked the PHPinfo and the session.save _path, it says /var/php.sessions under Local Value and Master Value

The document root seems fine but I have not called the web hosts about this as it is on their website.

The config.inc.php file worked fine when I was using PHP 5.

When I check the error log - which I hadn't done before my original post, I am also getting  this error -

PHP Warning:  session_start(): Cannot start session when headers already sent in /hermes/bosnacweb04/bosnacweb04aj/b717/nf.tiredofbeingrippedoff/public_html/yarnextras.com/includes/config.inc.php on line 30
Most Valuable Expert 2018
Distinguished Expert 2019
Commented:
Hmm. The 'Headers Already Sent' error means that some data has been output before you call session_start(). It indicates that line 30 is the where you're calling session_start() but the config code you posted earlier is only about 20 lines long.

Now you know the storage location for sessions under PHP7, it would be handy if you knew what that was under PHP5. If it's different, then you've potentially identified the problem. I would certainly raise a ticket with your hosting company about this. The error you're getting is not specifically related to PHP7 - it's more likely a server config issue, so would need bumping to tech support.
Wanda MarstonCreative Director

Author

Commented:
Thank to all for your input.