Skip to content

Latest commit

 

History

History
438 lines (405 loc) · 11.2 KB

php-ii-dec-2021.md

File metadata and controls

438 lines (405 loc) · 11.2 KB

PHP Fundamentals II - Dec 2021

TODO

Example of preg_replace_callback_array()

Homework

  • For 10 Dec 2021 Lab: Prepared Statements
Complete the following:

Create a prepared statement script.
Add a try/catch construct.
Add a new customer record binding the customer parameters.

Lab: Stored Procedure

Complete the following:

Create a stored procedure script.
Add the SQL to the database.
Call the stored procedure with parameters.

Lab: Transaction

Complete the following:

Create a transaction script.
Execute two SQL statements.
Handle any exceptions.

Lab: Validate an Email Address

Use preg_match() to validate an email address

VM

To get rid of the message "System Problem Detected"

sudo rm /var/crash/*

To install Composer: have a look here: https://getcomposer.org

Instructions to update phpMyAdmin in the VM???

  • In the VM, open a terminal window and do this:
// NOTE: work in progress
cd \tmp
wget https://files.phpmyadmin.net/phpMyAdmin/5.1.1/phpMyAdmin-5.1.1-all-languages.zip
sudo unzip phpMyAdmin-5.1.1-all-languages.zip -d /usr/share
sudo mv /usr/share/phpMyAdmin-5.1.1-all-languages /usr/share/phpmyadmin

Q & A

Get example of using __call() to implement a "plugin" architecture

Class Notes

Get vhost (virtual host) definition to sandbox in VM to use as a website

  • From a terminal window (command prompt):
    • Run gedit as the root user:
sudo gedit
  • Open the file /etc/hosts
  • Add an entry to the local hosts file to simulate a server named "sandbox"
127.0.0.1 sandbox
  • Save the file
  • Open a new file (press the "+" icon next to "Open")
  • Paste this into the editor:
<VirtualHost *:80>
   ServerName sandbox
   DocumentRoot /home/vagrant/Zend/workspaces/DefaultWorkspace/sandbox
   <Directory /home/vagrant/Zend/workspaces/DefaultWorkspace/sandbox/>
       Options Indexes FollowSymlinks MultiViews
       AllowOverride All
       Require all granted
   </Directory>
</VirtualHost>
  • Save as /etc/apache2/sites-available/sandbox.conf
  • Exit gedit
  • Test the new simulated server
ping -c3 sandbox
  • Enable the new vhost
sudo a2ensite sandbox
  • Restart Apache
sudo service apache2 restart
<?php
namespace A\X;
class Xyz
{
	public string $fname = '';
	public string $lname = '';
	public function getDate()
	{
		return date('Y-m-d');
	}
	public function getInfo()
	{
		$str = $this->getDate() . "\n";
		$str .= $this->fname . ' ' . $this->lname;
		return $str;
	}
}
  • Example of program file that uses the class
    • Does not use an autoloader in this example as there's only 1 class and file
<?php
require_once __DIR__ . '/A/X/Xyz.php';
use A\X\Xyz;
$temp = new Xyz();
$temp->fname = 'Fred';
$temp->lname = 'Flintstone';
echo $temp->getInfo();
<?php

class Universal {
	protected array $whatever = [];
    public function __set($prop, $value)
    {
		$this->whatever[$prop ] = $value;
    }
    public function __get($prop)
    {
		return $this->whatever[$prop ] ?? '';
    }
}

$uni = new Universal();
$uni->firstName = 'Fred';
$uni->lastName = 'Flintstone';
echo $uni->firstName . ' ' . $uni->lastName;
var_dump($uni);
<?php
interface EncryptInterface
{
	public function encrypt() : string;
}
interface DecryptInterface
{
	public function decrypt(string $text) : string;
}
abstract class Security implements EncryptInterface, DecryptInterface
{
	const SUPPORTED_ALGOS = ['reverse','openssl'];
	public function __construct(
		public string $text,
		public string $algo)
	{}
}
class Reverse extends Security
{
	public function encrypt() : string
	{
		return strrev($this->text);
	}
	public function decrypt(string $text) : string
	{
		return strrev($text);
	}
}
class OpenSsl extends Security
{
	public function encrypt() : string
	{
		return openssl_encrypt($this->text);
	}
	public function decrypt(string $text) : string
	{
		return openssl_decrypt($text);
	}
}
$security = new Reverse('The quick brown fox jumped over the fence', 'reverse');
$encrypted = $security->encrypt();
echo $security->decrypt($encrypted);

<?php
interface T
{
	const WHATEVER = 'whatever';
	public function getName() : string;
}
class A implements T
{
	public string $name = 'TEST';
	public function getName() : string
	{
		return $this->name;
	}
}
class B extends A
{
	public string $status = 'OK';
}
class C extends B
{
	public float $amount = 99.99;
}
class X implements T
{
	public string $xyz = 'XYZ';
	public function getName() : string
	{
		return $this->xyz;
	}
}

function test(T $a)
{
	echo $a->getName() . "\n";
}

$a = new A();
test($a);

$b= new B();
test($b);

$c = new C();
test($c);

$x = new X();
test($x);

// output:
/*
TEST
TEST
TEST
XYZ


------------------
(program exited with code: 0)
 */
<?php
$sql = 'Insert into User (firstName, lastName, phoneNumber, gender) values (';
foreach ($userDetails->getArrayCopy() as $value) $sql .= "'" . $value . "',";
$sql = substr($sql, 0, -1);
$sql .= ');';
  • Same example as above, but using prepared statements
<?php
$sql = 'Insert into User (firstName, lastName, phoneNumber, gender) values (?,?,?,?)';
$stmt = $this->pdo->prepare($sql);
$result = $stmt->execute($userDetails->getArrayCopy());
  • Example from Marc's codebase
<?php
namespace MX\Models\DB;
use PDO;
use PDOException;
use Throwable;
class DB
{
	public string $servername;
	public string $username;
	public string $password;
	public string $dbname;
	// this needs to be supplied by the calling program
	public function dbConnection(array $config)
	{
		$servername = $config['servername'];
		$username = $config['username'];
		$password = $config['password'];
		$dbname = $config['dbname'];
		$dsn = 'mysql:host=localhost;dbname=' . $dbname;
		try {
		    $conn = new PDO($dsn, $username, $password);\
		    // for PHP 7.4 only:
		    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		} catch (Throwable $t) {
		   error_log($t->getMessage());
		   $conn = FALSE;
		}
		return $conn;
	}
}
  • Using the PDO instance ($conn)
// from UserController
    public function DisplayUsers(array $config)
    {
	      $db = new DB($config);
	      $db = $db->dbConnection();
	      $sql = "SELECT * FROM users";
	      $result = $conn->query($sql);
	      return $result;	// this will be a PDOStatement instance
    }
  • Display the results
<!-- comes from UserController::displayUsers() -->
<?php while($row = $result->fetch(PDO::FETCH_ASSOC)) : ?>
<!-- display the results from the array -->
<?php endwhile;?>

REST Examples

<?php
$data = '<script>alert("test");</script>The Rest of the Data';
echo htmlspecialchars($data);

// output:
// &lt;script&gt;alert(&quot;test&quot;);&lt;/script&gt;The Rest of the Data

Resources

Previous class repos:

Web services examples:

<?php
class Test
{
	public string $name = 'Fred';
	protected int $status = 123;
	public function getStatus()
	{
		return $this->status;
	}
}

$test = new Test();
echo $test->getStatus() . "\n";
var_dump($test);

// problem #1: can't access non-public properties
$json = json_encode($test, JSON_PRETTY_PRINT);
echo $json . "\n";

// problem #2: the original object class is not restored
$obj = json_decode($json);
var_dump($obj);

SOAP vs. REST: https://www.ateam-oracle.com/post/performance-study-rest-vs-soap-for-mobile-applications

Errata

class GuestUser extends UserEntity {
    // **** NOT ALLOWED!!! **** //
    public function setFirstName($firstName, $mi = null) {
        $this->firstname = ($mi) ? $firstName . ' ' . $mi : $firstName;
    }
}