<?php
/**
* Physical address.
*/
class Address {
const ADDRESS_TYPE_RESIDENCE = 1;
const ADDRESS_TYPE_BUSINESS = 2;
const ADDRESS_TYPE_PARK = 3;
// Address types.
static public $valid_address_types = array(
Address::ADDRESS_TYPE_RESIDENCE => 'Residence',
Address::ADDRESS_TYPE_BUSINESS => 'Business',
Address::ADDRESS_TYPE_PARK => 'Park',
);
// Street address.
public $street_address_1;
public $street_address_2;
// Name of the City.
public $city_name;
// Name of the subdivison.
public $subdivision_name;
// Postal code.
protected $_postal_code;
// Name of the Country.
public $country_name;
// Primary key of an Address.
protected $_address_id;
// Address type id.
protected $_address_type_id;
// When the record was created and last updated.
protected $_time_created;
protected $_time_updated;
/**
* Constructor.
* @param array $data Optional array of property names and values.
*/
function __construct($data = array()) {
$this->_time_created = time();
// Ensure that the Address can be populated.
if (!is_array($data)) {
trigger_error('Unable to construct address with a ' . get_class($name));
}
// If there is at least one value, populate the Address with it.
if (count($data) > 0) {
foreach ($data as $name => $value) {
// Special case for protected properties.
if (in_array($name, array(
'time_created',
'time_updated',
))) {
$name = '_' . $name;
}
$this->$name = $value;
}
}
}
/**
* Magic __get.
* @param string $name
* @return mixed
*/
function __get($name) {
// Postal code lookup if unset.
if (!$this->_postal_code) {
$this->_postal_code = $this->_postal_code_guess();
}
// Attempt to return a protected property by name.
$protected_property_name = '_' . $name;
if (property_exists($this, $protected_property_name)) {
return $this->$protected_property_name;
}
// Unable to access property; trigger error.
trigger_error('Undefined property via __get: ' . $name);
return NULL;
}
/**
* Magic __set.
* @param string $name
* @param mixed $value
*/
function __set($name, $value) {
// Only set valid address type id.
if ('address_type_id' == $name) {
$this->_setAddressTypeId($value);
return;
}
// Allow anything to set the postal code.
if ('postal_code' == $name) {
$this->$name = $value;
return;
}
// Unable to access property; trigger error.
trigger_error('Undefined or unallowed property via __set(): ' . $name);
}
/**
* Magic __toString.
* @return string
*/
function __toString() {
return $this->display();
}
/**
* Guess the postal code given the subdivision and city name.
* @todo Replace with a database lookup.
* @return string
*/
protected function _postal_code_guess() {
$db = Database::getInstance();
$mysqli = $db->getConnection();
$sql_query = 'SELECT postal_code ';
$sql_query.= 'FROM location ';
$city_name = $mysqli->real_escape_string($this->city_name);
$sql_query .= 'WHERE city_name = "' . $city_name . '" ';
$subdivision_name = $mysqli->real_escape_string($this->subdivision_name);
$sql_query .= 'AND subdivision_name = "' .$subdivision_name . '"';
$result = $mysqli->query($sql_query);
if ($row = $result->fetch_assoc()){
return $row['postal_code'];
}
}
/**
* Display an address in HTML.
* @return string
*/
function display() {
$output = '';
// Street address.
$output .= $this->street_address_1;
if ($this->street_address_2) {
$output .= '<br/>' . $this->street_address_2;
}
// City, Subdivision Postal.
$output .= '<br/>';
$output .= $this->city_name . ', ' . $this->subdivision_name;
$output .= ' ' . $this->postal_code;
// Country.
$output .= '<br/>';
$output .= $this->country_name;
return $output;
}
/**
* Determine if an address type is valid.
* @param int $address_type_id
* @return boolean
*/
static public function isValidAddressTypeId($address_type_id) {
return array_key_exists($address_type_id, self::$valid_address_types);
}
/**
* If valid, set the address type id.
* @param int $address_type_id
*/
protected function _setAddressTypeId($address_type_id) {
if (self::isValidAddressTypeId($address_type_id)) {
$this->_address_type_id = $address_type_id;
}
}
}
<?php
/**
* mysqli database: only one connection is allowed
*/
class Database{
private $_connection;
//store the single instance
private static $_instance;
/**
* get an instance of the database
* @return Database
*
*/
public static function getInstance(){
if (!self::$_instance){
self::$_instance= new self();
}
return self::$_instance;
}
/**
* constructor
*/
public function __construct(){
$this->connection = new mysqli('localhost','username','pass','dbname');
//error handling
if (mysqli_connect_error()){
trigger_error('Failed to connect to MySql: '.mysqli_connect_error(),E_USER_ERROR);
}
}
/**
* Empty clone magic method to prevent duplication.
*/
private function __clone(){}
/**
* get the mysqli connection
*/
public function getConnection(){
return $this->_connection;
}
}
<?php
require 'class.Address.inc';
require 'class.Database.inc';
echo '<h2>Instantiating Address</h2>';
$address = new Address;
echo '<h2>Setting properties...</h2>';
$address->street_address_1 = '555 Fake Street';
$address->city_name = 'Townsville';
$address->subdivision_name = 'State';
$address->country_name = 'United States of America';
$address->address_type_id = 1;
echo $address;
echo '<h2>Testing Address __construct with an array</h2>';
$address_2 = new Address(array(
'street_address_1' => '123 Phony Ave',
'city_name' => 'Villageland',
'subdivision_name' => 'Region',
'postal_code' => '67890',
'country_name' => 'Canada',
));
echo $address_2;
ASKER
public function __construct(){
$this->connection = new mysqli('localhost','username','pass','dbname');
//error handling
if (mysqli_connect_error()){
trigger_error('Failed to connect to MySql: '.mysqli_connect_error(),E_USER_ERROR);
}
ASKER
ASKER
ASKER
ASKER
CREATE TABLE IF NOT EXISTS `address` (
`address_id` int(11) NOT NULL AUTO_INCREMENT,
`address_type_id` int(11) NOT NULL,
`time_created` int(11) NOT NULL,
`time_updated` int(11) NOT NULL,
`street_address_1` varchar(255) NOT NULL,
`street_address_2` varchar(255) NOT NULL,
`city_name` varchar(255) NOT NULL,
`subdivision_name` varchar(255) NOT NULL,
`postal_code` varchar(20) NOT NULL,
`country_name` varchar(255) NOT NULL,
PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
INSERT INTO `address` (`address_id`, `address_type_id`, `time_created`, `time_updated`, `street_address_1`, `street_address_2`, `city_name`, `subdivision_name`, `postal_code`, `country_name`) VALUES
(1, 1, 762483360, 0, '300 Oracle Parkway', '', 'Redwood City', 'California', '94065', 'United States');
CREATE TABLE IF NOT EXISTS `location` (
`location_id` int(11) NOT NULL AUTO_INCREMENT,
`city_name` varchar(255) NOT NULL,
`city_latitude` double NOT NULL,
`city_longitude` double NOT NULL,
`subdivision_name` varchar(255) NOT NULL,
`postal_code` varchar(20) NOT NULL,
PRIMARY KEY (`location_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
INSERT INTO `location` (`location_id`, `city_name`, `city_latitude`, `city_longitude`, `subdivision_name`, `postal_code`) VALUES
(1, 'Townsville', 38.7153408676386, -75.0866805016994, 'State', '12345'),
(2, 'Villageland', 33.1156463623047, -117.120277404785, 'Region', '67890'),
(3, 'Hamlet', 43.6666296, -92.9746367, 'Territory', '34567'),
(4, 'Redwood City', 37.5311965942383, -122.2646484375, 'California', '94065');
ASKER
function __construct($data = array()) {
$this->_time_created = time();
// Ensure that the Address can be populated.
if (!is_array($data)) {
trigger_error('Unable to construct address with a ' . get_class($name));
}
// If there is at least one value, populate the Address with it.
if (count($data) > 0) {
foreach ($data as $name => $value) {
// Special case for protected properties.
if (in_array($name, array(
'time_created',
'time_updated',
))) {
$name = '_' . $name;
}
$this->$name = $value;
}
}
}
ASKER
ASKER
ASKER
I am using my database connection (which I do not show to experts-exchange.com)I will post a new version of the class.Database.inc in a moment. I just want to make sure you understand the change I'm making and how to find out where the error has been hiding.
<?php // class.Database.inc
/**
* mysqli database: only one connection is allowed
*/
class Database
{
private $_connection;
//store the single instance
private static $_instance;
/**
* get an instance of the database
* @return Database
*/
public static function getInstance(){
if (!self::$_instance){
self::$_instance= new self();
}
return self::$_instance;
}
/**
* constructor
*/
public function __construct(){
$this->_connection = new mysqli('localhost','username','pass','dbname');
//error handling
if ($this->_connection->_connect_error){
trigger_error('Failed to connect to MySql: '.mysqli_connect_error(),E_USER_ERROR);
}
}
/**
* Empty clone magic method to prevent duplication.
*/
private function __clone(){}
/**
* get the mysqli connection
*/
public function getConnection(){
return $this->_connection;
}
}
<?php // RWY_temp_rgb192.php
error_reporting(E_ALL);
/**
* mysqli database: only one connection is allowed (BUT THIS IS NOT A TRUE SINGLETON)
*/
class Database
{
private $_connection;
//store the single instance
private static $_instance;
/**
* get an instance of the database
* @return Database
*/
public static function getInstance(){
if (!self::$_instance){
self::$_instance= new self();
}
return self::$_instance;
}
/**
* constructor
*/
public function __construct(){
$this->_connection = new mysqli('localhost','user','pass','name');
//error handling
if ($this->_connection->connect_error){
trigger_error('Failed to connect to MySql: '.mysqli_connect_error(),E_USER_ERROR);
}
}
/**
* Empty clone magic method to prevent duplication.
*/
private function __clone(){}
/**
* get the mysqli connection
*/
public function getConnection(){
return $this->_connection;
}
}
// CREATE INSTANCES
$db1 = new Database;
$db2 = $db1->getConnection();
$db3 = new Database;
$db4 = $db3->getConnection();
$db5 = $db3->getConnection();
// THIS WILL PROVE THAT THERE ARE TWO CONNECTIONS (NO ECHO)
if ($db2 === $db4) echo 'EQUAL';
// THIS WILL SHOW THAT CONNECTIONS FROM THE SAME INSTANCE ARE EQUAL
if ($db4 === $db5) echo 'CONNECTION EQUAL';
<?php // RAY_database_singleton.php
error_reporting(E_ALL);
// SINGLETON DATA BASE CONNECTION CLASS
class Database
{
// CLASS PROPERTIES ARE ALL PRIVATE
private static $_connection;
private static $_instance;
// CONNECTION VALUES
const DB_HOST = 'localhost';
const DB_USER = 'user';
const DB_PASS = 'pass';
const DB_NAME = 'name';
// NULLIFY THE CLONE
private function __clone() {}
// OUR ONLY PUBLIC METHOD RETURNS THE CONNECTION
public static function getConnection()
{
if (!self::$_instance) self::$_instance = new self();
return self::$_connection;
}
// CONSTRUCTOR RETURNS THE CONNECTION
private function __construct()
{
self::$_connection
= new mysqli
( self::DB_HOST
, self::DB_USER
, self::DB_PASS
, self::DB_NAME
)
;
if (self::$_connection->connect_error)
{
trigger_error(self::$_connection->connect_error, E_USER_ERROR);
}
}
}
$mysql1 = database::getConnection();
$mysql2 = database::getConnection();
// PROVE THAT THESE ARE THE SAME OBJECT http://php.net/manual/en/language.oop5.object-comparison.php
if ($mysql1 === $mysql2) echo 'EQUAL';
HTH, ~Ray
ASKER
ASKER
ASKER
ASKER
<?php
/**
* Physical address.
*/
class Address {
const ADDRESS_TYPE_RESIDENCE = 1;
const ADDRESS_TYPE_BUSINESS = 2;
const ADDRESS_TYPE_PARK = 3;
// Address types.
static public $valid_address_types = array(
Address::ADDRESS_TYPE_RESIDENCE => 'Residence',
Address::ADDRESS_TYPE_BUSINESS => 'Business',
Address::ADDRESS_TYPE_PARK => 'Park',
);
// Street address.
public $street_address_1;
public $street_address_2;
// Name of the City.
public $city_name;
// Name of the subdivison.
public $subdivision_name;
// Postal code.
protected $_postal_code;
// Name of the Country.
public $country_name;
// Primary key of an Address.
protected $_address_id;
// Address type id.
protected $_address_type_id;
// When the record was created and last updated.
protected $_time_created;
protected $_time_updated;
/**
* Constructor.
* @param array $data Optional array of property names and values.
*/
function __construct($data = array()) {
$this->_time_created = time();
// Ensure that the Address can be populated.
if (!is_array($data)) {
trigger_error('Unable to construct address with a ' . get_class($name));
}
// If there is at least one value, populate the Address with it.
if (count($data) > 0) {
foreach ($data as $name => $value) {
// Special case for protected properties.
if (in_array($name, array(
'time_created',
'time_updated',
))) {
$name = '_' . $name;
}
$this->$name = $value;
}
}
}
/**
* Magic __get.
* @param string $name
* @return mixed
*/
function __get($name) {
// Postal code lookup if unset.
if (!$this->_postal_code) {
$this->_postal_code = $this->_postal_code_guess();
}
// Attempt to return a protected property by name.
$protected_property_name = '_' . $name;
if (property_exists($this, $protected_property_name)) {
return $this->$protected_property_name;
}
// Unable to access property; trigger error.
trigger_error('Undefined property via __get: ' . $name);
return NULL;
}
/**
* Magic __set.
* @param string $name
* @param mixed $value
*/
function __set($name, $value) {
// Only set valid address type id.
if ('address_type_id' == $name) {
$this->_setAddressTypeId($value);
return;
}
// Allow anything to set the postal code.
if ('postal_code' == $name) {
$this->$name = $value;
return;
}
// Unable to access property; trigger error.
trigger_error('Undefined or unallowed property via __set(): ' . $name);
}
/**
* Magic __toString.
* @return string
*/
function __toString() {
return $this->display();
}
/**
* Guess the postal code given the subdivision and city name.
* @todo Replace with a database lookup.
* @return string
*/
protected function _postal_code_guess() {
$db = Database::getInstance();
//var_dump($db);
$mysqli = $db->getConnection();
//echo 'what';
//var_dump($mysqli);
$city_name = /*$mysqli->real_escape_string(*/$this->city_name/*)*/;
//$sql_query .= 'WHERE city_name = "' . $city_name . '" ';
$subdivision_name = /*$mysqli->real_escape_string(*/$this->subdivision_name/*)*/;
//$sql_query .= 'AND subdivision_name = "' .$subdivision_name . '"';
$result = $mysqli->query($sql_query);
if ($row = $result->fetch_assoc()){
return $row['postal_code'];
}
//var_dump($db);
//var_dump($mysqli);
}
/**
* Display an address in HTML.
* @return string
*/
function display() {
$output = '';
// Street address.
$output .= $this->street_address_1;
if ($this->street_address_2) {
$output .= '<br/>' . $this->street_address_2;
}
// City, Subdivision Postal.
$output .= '<br/>';
$output .= $this->city_name . ', ' . $this->subdivision_name;
$output .= ' ' . $this->postal_code;
// Country.
$output .= '<br/>';
$output .= $this->country_name;
return $output;
}
/**
* Determine if an address type is valid.
* @param int $address_type_id
* @return boolean
*/
static public function isValidAddressTypeId($address_type_id) {
return array_key_exists($address_type_id, self::$valid_address_types);
}
/**
* If valid, set the address type id.
* @param int $address_type_id
*/
protected function _setAddressTypeId($address_type_id) {
if (self::isValidAddressTypeId($address_type_id)) {
$this->_address_type_id = $address_type_id;
}
}
}
<?php
error_reporting(E_ALL);
require 'class.Address.inc';
require 'class.Database.inc';
echo '<h2>Instantiating Address</h2>';
$address = new Address;
echo '<h2>Setting properties...</h2>';
$address->street_address_1 = '555 Fake Street';
$address->city_name = 'Townsville';
$address->subdivision_name = 'State';
$address->country_name = 'United States of America';
$address->address_type_id = 1;
//var_dump($address);
//var_dump($db);
//var_dump($mysqli);
echo $address;
echo '<h2>Testing Address __construct with an array</h2>';
$address_2 = new Address(array(
'street_address_1' => '123 Phony Ave',
'city_name' => 'Villageland',
'subdivision_name' => 'Region',
'postal_code' => '67890',
'country_name' => 'Canada',
));
//var_dump($address2);
echo $address_2;
ASKER
ASKER
PHP is a widely-used server-side scripting language especially suited for web development, powering tens of millions of sites from Facebook to personal WordPress blogs. PHP is often paired with the MySQL relational database, but includes support for most other mainstream databases. By utilizing different Server APIs, PHP can work on many different web servers as a server-side scripting language.
TRUSTED BY
Open in new window
Suggest you use our friend var_dump() to see what is contained in the variables.It may not be related, but this code looks a bit goofy, like perhaps it is incomplete? In the constructor at line 54 we have this:
trigger_error('Unable to construct address with a ' . get_class($name));
At that point the variable $name is undefined. Code smell.