Html form to .php that use 'include' for db connection


#1

Hello. Are trying to enter information into an html form then pass that to an .php to handle the form, The .php script use include ‘somefile.php’ to establish an data base connection. But it is not working. :thinking:
Output in web browser:

abc  
Fatal error: Uncaught Error: Call to undefined method connect2db::query() in /opt/lampp/htdocs/process2sql.php:8 Stack trace: #0 {main} thrown in /opt/lampp/htdocs/process2sql.php on line 8

The html form is a place holder atm it wil later take useful information. but it is used to trigger the handle script atm.
Any suggestion to avoid error are welcome :smile:
Code snippets bellow are in order form.html, handle.php and connect2db.php

File name: phpTest.html

<!DOCKTYPE html>
<html>

<head>
	<title>Fun web project</title>
</head>

<body>
	<form action="process2sql.php" method="POST">
		<label for="text"><a href="https://duckduckgo.com/" target="blank">Type</a> text here: </label>
		<input type="text" name="text" id="text" placeholder="Bitty bot">
		<input type="submit" name="Submit">
	</form>
</body>
</html>

File name: process2sql.php

<?php
	include 'dbconnect.php';

	echo $_POST['text'];
	$pdo = new connect2db();
	#$pdo = o->connect();
	#var_dump($pdo);
	$stmt = $pdo->query('SELECT * FROM registration where fname = \'sofia\'');
	#while($row = $stmt->fetch()) {
	#	echo $row['fname'] . ' ' . $row['lname'] . '<br>';
	#}
?>

File name: dbconnect.php

#/opt/lampp/bin/mysql -u root
class connect2db {
	private $host;
	private $db;
	private $user;
	private $pass;
	private $charset;
	
	private $options = [
	    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
	    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
	    PDO::ATTR_EMULATE_PREPARES   => false,
	];
	
	public function connect() {
		$this->host = '127.0.0.1';
		$this->db = 'mywebdb';
		$this->user = 'webroot';
		$this->pass = '1234';
		$this->charset = 'utf8mb4';
		try {
			#public $dsn = "mysql:host=$this->host;dbname=$this->db;charset=$this->charset";
			$dsn = 'mysql:host=127.0.0.1;dbname=mywebdb;charset=utf8mb4';
			$pdo = new PDO($dsn, $user, $pass, $options);
		}
		catch (\PDOException $e) {
			echo "Error is imenent";
		    throw new \PDOException($e->getMessage(), (int)$e->getCode());
		}
		return $pdo;
	}
}

#$runopt = new connect2db();

?>

#2

Are they all in the same directory with the same permissions?


#3

Rather than trying to figure out what you did wrong I will just show you how to do it right. (Except dont echo the error line like it shows. For testing only.)

<?php
//----------------------------------------------------------------------------------------
// Database Connection
//----------------------------------------------------------------------------------------
define('DB_TYPE', 'mysql'); // Database Type
define('DB_NAME', 'test'); // Database Name
define('DB_USER', 'root'); // Database Username
define('DB_PASSWORD', ''); // Database Password
define('DB_HOST', 'localhost'); // Database Hostname
define('DB_CHARSET', 'utf8'); // Database Charset

class MysqlConnection
{
    /**
     * @return mixed|PDO
     */
    public function connect()
    {
        try
        {
            $dsn = DB_TYPE . ":host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
            $opt = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
                , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
                , PDO::ATTR_EMULATE_PREPARES => false];
            return new PDO($dsn, DB_USER, DB_PASSWORD, $opt);
        } catch (\PDOException $e) {
            echo $error = $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
            die('<h1><span style="color:red">FATAL ERROR: No Database Connection</span></h1>');
        }
    }
}

$db = new MysqlConnection();
$pdo = $db->connect();

$sql = 'SELECT * FROM mytable';
$stmt = $pdo->query($sql);
foreach ($stmt as $row) {
    print_r($row);
}

#4

Your class only has one method, connect(), so, trying to call a method named query() on an instance of that class won’t work.

Given the commented out lines of code, which at one point made an instance of the class then called the connect() method, which is a needless step, this code may have worked, but not with the various modifications that have been made to it. If you are just starting out and don’t understand OOP, all you will be doing is fighting problems and might as well forget that you ever saw this class code. Just make a PDO connection using your connection credentials and set the various attributes inside the dbconnect.php file.

The only thing this class is doing that is worth keeping is setting some of the attributes to commonly used values, but even that should allow call-time values to be used too. The rest of the class code either won’t work as written (local variables that don’t exist) or is using bad programming practices with a lot of unneeded lines of code.

Some of the problems -

  1. Classes should NOT contain application specific values. The connection credentials should not be hard-code in the class and/or defined as properties but not actually used. You should not need to edit the values in the class if you move the code to a different host. In fact, by having the connection credentials inside the class, you cannot make more than one instance of the class. The dsn shouldn’t be inside the class either, so that you can reuse the class with other database types.

  2. There’s no good reason to catch an exception just to re-throw it with the same values that you just caught. The try/catch logic in this class is pointless and should be removed.

  3. If the only thing this class is doing is creating the connection, it’s just a wrapper for the PDO class and is a waste of typing. If on the other hand, this class added functionality to the PDO class, such as adding a general purpose prepared/non-prepared query method, then it would be doing something useful. Some other useful things this class could do would be to have combined query/fetch methods that would both execute a supplied SELECT query and fetch one row or fetch a set of rows.

What this class should do is extend the PDO class. There should be a __construct() method to make the connection, with the same call-time parameters as the PDO class. The constructor code would set the various attributes to the commonly used values. There should be a general purpose prepared/non-prepared query() method that accepts the sql query statement and a second optional call-time parameter that consists of an array of input values. If the optional array of input values is empty, the method code should just call the PDO query() method. If the optional array of input values is not empty, the method code should call the PDO prepare() method, then the PDOStatement execute() method and supply the array of parameters to the execute call. In both of these cases, this method should return the PDOStatement object to the calling code.