Php: Learning OOP, Static vs normal method - php

This is my first post in Stack Overflow so bear with me if I don't conform to any of the rules. I have been scripting in php for a while now but have never actually used any of its OOP side. I have been doing a training course on-line (not sure if i'm aloud to state which one because of copyright ?)
Either way during the course the programmer made a few static methods inside of one of his class, I decided i didn't want to make mine static. Here is the code he writ below. I did mine all the same just with different references to the variables in the code like $this->variable.
`<?php
// If it's going to need the database, then it's
// probably smart to require it before we start.
require_once(LIB_PATH.DS.'database.php');
class Photograph extends DatabaseObject {
protected static $table_name="photographs";
protected static $db_fields=array('id', 'filename', 'type', 'size', 'caption');
public $id;
public $filename;
public $type;
public $size;
public $caption;
private $temp_path;
protected $upload_dir="images";
public $errors=array();
protected $upload_errors = array(
// http://www.php.net/manual/en/features.file-upload.errors.php
UPLOAD_ERR_OK => "No errors.",
UPLOAD_ERR_INI_SIZE => "Larger than upload_max_filesize.",
UPLOAD_ERR_FORM_SIZE => "Larger than form MAX_FILE_SIZE.",
UPLOAD_ERR_PARTIAL => "Partial upload.",
UPLOAD_ERR_NO_FILE => "No file.",
UPLOAD_ERR_NO_TMP_DIR => "No temporary directory.",
UPLOAD_ERR_CANT_WRITE => "Can't write to disk.",
UPLOAD_ERR_EXTENSION => "File upload stopped by extension."
);
// Pass in $_FILE(['uploaded_file']) as an argument
public function attach_file($file) {
// Perform error checking on the form parameters
if(!$file || empty($file) || !is_array($file)) {
// error: nothing uploaded or wrong argument usage
$this->errors[] = "No file was uploaded.";
return false;
} elseif($file['error'] != 0) {
// error: report what PHP says went wrong
$this->errors[] = $this->upload_errors[$file['error']];
return false;
} else {
// Set object attributes to the form parameters.
$this->temp_path = $file['tmp_name'];
$this->filename = basename($file['name']);
$this->type = $file['type'];
$this->size = $file['size'];
// Don't worry about saving anything to the database yet.
return true;
}
}
public function save() {
// A new record won't have an id yet.
if(isset($this->id)) {
// Really just to update the caption
$this->update();
} else {
// Make sure there are no errors
// Can't save if there are pre-existing errors
if(!empty($this->errors)) { return false; }
// Make sure the caption is not too long for the DB
if(strlen($this->caption) > 255) {
$this->errors[] = "The caption can only be 255 characters long.";
return false;
}
// Can't save without filename and temp location
if(empty($this->filename) || empty($this->temp_path)) {
$this->errors[] = "The file location was not available.";
return false;
}
// Determine the target_path
$target_path = SITE_ROOT .DS. 'public' .DS. $this->upload_dir .DS. $this->filename;
// Make sure a file doesn't already exist in the target location
if(file_exists($target_path)) {
$this->errors[] = "The file {$this->filename} already exists.";
return false;
}
// Attempt to move the file
if(move_uploaded_file($this->temp_path, $target_path)) {
// Success
// Save a corresponding entry to the database
if($this->create()) {
// We are done with temp_path, the file isn't there anymore
unset($this->temp_path);
return true;
}
} else {
// File was not moved.
$this->errors[] = "The file upload failed, possibly due to incorrect permissions on the upload folder.";
return false;
}
}
}
public function destroy() {
// First remove the database entry
if($this->delete()) {
// then remove the file
// Note that even though the database entry is gone, this object
// is still around (which lets us use $this->image_path()).
$target_path = SITE_ROOT.DS.'public'.DS.$this->image_path();
return unlink($target_path) ? true : false;
} else {
// database delete failed
return false;
}
}
public function image_path() {
return $this->upload_dir.DS.$this->filename;
}
public function size_as_text() {
if($this->size < 1024) {
return "{$this->size} bytes";
} elseif($this->size < 1048576) {
$size_kb = round($this->size/1024);
return "{$size_kb} KB";
} else {
$size_mb = round($this->size/1048576, 1);
return "{$size_mb} MB";
}
}
// Common Database Methods
public static function find_all() {
return self::find_by_sql("SELECT * FROM ".self::$table_name);
}
public static function find_by_id($id=0) {
global $database;
$result_array = self::find_by_sql("SELECT * FROM ".self::$table_name." WHERE id=".$database->escape_value($id)." LIMIT 1");
return !empty($result_array) ? array_shift($result_array) : false;
}
public static function find_by_sql($sql="") {
global $database;
$result_set = $database->query($sql);
$object_array = array();
while ($row = $database->fetch_array($result_set)) {
$object_array[] = self::instantiate($row);
}
return $object_array;
}
private static function instantiate($record) {
// Could check that $record exists and is an array
$object = new self;
// Simple, long-form approach:
// $object->id = $record['id'];
// $object->username = $record['username'];
// $object->password = $record['password'];
// $object->first_name = $record['first_name'];
// $object->last_name = $record['last_name'];
// More dynamic, short-form approach:
foreach($record as $attribute=>$value){
if($object->has_attribute($attribute)) {
$object->$attribute = $value;
}
}
return $object;
}
private function has_attribute($attribute) {
// We don't care about the value, we just want to know if the key exists
// Will return true or false
return array_key_exists($attribute, $this->attributes());
}
protected function attributes() {
// return an array of attribute names and their values
$attributes = array();
foreach(self::$db_fields as $field) {
if(property_exists($this, $field)) {
$attributes[$field] = $this->$field;
}
}
return $attributes;
}
protected function sanitized_attributes() {
global $database;
$clean_attributes = array();
// sanitize the values before submitting
// Note: does not alter the actual value of each attribute
foreach($this->attributes() as $key => $value){
$clean_attributes[$key] = $database->escape_value($value);
}
return $clean_attributes;
}
// replaced with a custom save()
// public function save() {
// // A new record won't have an id yet.
// return isset($this->id) ? $this->update() : $this->create();
// }
public function create() {
global $database;
// Don't forget your SQL syntax and good habits:
// - INSERT INTO table (key, key) VALUES ('value', 'value')
// - single-quotes around all values
// - escape all values to prevent SQL injection
$attributes = $this->sanitized_attributes();
$sql = "INSERT INTO ".self::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUES ('";
$sql .= join("', '", array_values($attributes));
$sql .= "')";
if($database->query($sql)) {
$this->id = $database->insert_id();
return true;
} else {
return false;
}
}
public function update() {
global $database;
// Don't forget your SQL syntax and good habits:
// - UPDATE table SET key='value', key='value' WHERE condition
// - single-quotes around all values
// - escape all values to prevent SQL injection
$attributes = $this->sanitized_attributes();
$attribute_pairs = array();
foreach($attributes as $key => $value) {
$attribute_pairs[] = "{$key}='{$value}'";
}
$sql = "UPDATE ".self::$table_name." SET ";
$sql .= join(", ", $attribute_pairs);
$sql .= " WHERE id=". $database->escape_value($this->id);
$database->query($sql);
return ($database->affected_rows() == 1) ? true : false;
}
public function delete() {
global $database;
// Don't forget your SQL syntax and good habits:
// - DELETE FROM table WHERE condition LIMIT 1
// - escape all values to prevent SQL injection
// - use LIMIT 1
$sql = "DELETE FROM ".self::$table_name;
$sql .= " WHERE id=". $database->escape_value($this->id);
$sql .= " LIMIT 1";
$database->query($sql);
return ($database->affected_rows() == 1) ? true : false;
// NB: After deleting, the instance of User still
// exists, even though the database entry does not.
// This can be useful, as in:
// echo $user->first_name . " was deleted";
// but, for example, we can't call $user->update()
// after calling $user->delete().
}
}
?>`
^^This is his complete Photograph() class and below is my photograph class
<?php
//This class will use the database so wil need the database class included
require_once(LIB_PATH.DS.'database.php');
class Photograph extends DatabaseObject
{
public $table_name = "photographs";
public $id;
public $filename;
public $type;
public $size;
public $caption;
public $all_photos = array();
private $temp_path;
protected $upload_dir = "images";
public $errors=array();
protected $upload_errors = array (
UPLOAD_ERR_OK => "No errors.",
UPLOAD_ERR_INI_SIZE => "Larger than upload_max_filesize.",
UPLOAD_ERR_FORM_SIZE => "Larger than form MAX_FILE_SIZE.",
UPLOAD_ERR_PARTIAL => "Partial Upload.",
UPLOAD_ERR_NO_FILE => "No File",
UPLOAD_ERR_NO_TMP_DIR => "No Temp Directory.",
UPLOAD_ERR_CANT_WRITE => "Cant write file to disk.",
UPLOAD_ERR_EXTENSION => "File uploaded stopped by extension."
);
//Pass in $_FILE['uploaded_file'] as an argument
public function attach_file($file) {
//Perform error checking on the form params
if(!$file || empty($file) || !is_array($file)) {
//error: nothing uploaded or wrong argument
$this->errors[] = "No file was uploaded.";
return false;
} elseif($file['error'] !=0) {
//error: report what php says went wrong
$this->errors[] = $this->upload_errors[$file['error']];
return false;
} else {
//Set object attributes to the forms params
$this->temp_path = $file['tmp_name'];
$this->filename = basename($file['name']);
$this->type = $file['type'];
$this->size = $file['size'];
//Dont worry about saving anything to database yet
return true;
}
}
public function save() {
//A new record wont have an id yet
if(isset($this->id)) {
$this->update();
//Really just to update the caption
} else {
//Make sure there are no errors
//Cant save if there are pre existing errors
if(!empty($this->errors)) { return false;}
//Make suer the caption is not to long for the database
if(strlen($this->caption) >= 255) {
$this->errors[] = "The caption can only be 255 characters long.";
return false;
}
//Cant save without the filename and temp location
if(empty($this->filename) || empty($this->temp_path)) {
$this->errors[] = "The file location was not available.";
return false;
}
//Determine the target path
$target_path = SITE_ROOT .DS. 'public' .DS.$this->upload_dir . DS. $this->filename;
//Make sure that the file doesn't already exist in that location
if(file_exists($target_path)) {
$this->errors[] = "The file {$this->filename} already exists.";
return false;
}
//Attempt to move the file
if(move_uploaded_file($this->temp_path, $target_path)) {
//Success
//Save a corresponding entry to the database
if($this->create()) {
//Were done with the temp path variable, The file isn't there any more
unset($this->temp_path);
return true;
}
} else {
//Error File was not moved
$this->errors[] = "The file upload failed, Possibly due to an incorrect permissions on upload folder.";
return false;
}
}
}
public function destroy($id,$filename) {
//First remove the database entry
if($this->delete($id)) {
//Then remove the file
$target_path = SITE_ROOT.DS.'public'.DS.$this->upload_dir.DS.$filename;
return unlink($target_path) ? true:false;
} else {
//Database delete failed
return false;
}
}
public function image_path() {
return $this->upload_dir.DS;
}
public function size_as_text($file_size) {
if($file_size < 1024) {
return "{$file_size} bytes";
} elseif($file_size < 1048576) {
$size_kb = round($file_size/1024);
return "{$size_kb} KB";
} else {
$size_mb = round($file_size/1048576, 1);
return "{size_mb} MB";
}
}
public function find_all() {
global $database;
$result = $this->find_by_sql("SELECT * FROM ".$this->table_name);
return $result;
}
public function find_all_photos() {
global $database;
$query = "SELECT * FROM {$this->table_name}";
$result = $database->query($query);
return $result;
}
public function find_by_id($id=0) {
global $database;
$result_array = $this->find_by_sql("SELECT * FROM " . $this->table_name . " WHERE id={$database->escape_value($id)} LIMIT 1");
return !empty($result_array) ? $result_array : false;
}
public function find_by_sql($sql="") {
global $database;
$result = $database->query($sql);
$object_array = $database->fetch_array($result);
$object = $this->instantiate($object_array);
//while($row = $database->fetch_array($result)) {
//$object_array[] = $this->instantiate($row);
//}
return $object_array;
}
private function instantiate($record) {
//Could check if $record exists and is an array
//Simple long form approach
//$object = new self;
$this->id= $record['id'];
$this->filename = $record['filename'];
$this->type = $record['type'];
$this->size = $record['size'];
$this->caption = $record['caption'];
//More dynamic, Short form approach
//foreach($record as $attribute=>$value) {
//if($object->has_attribute($attribute)) {
//$object->$attribute = $value;
//}
//}
//return $object;
}
private function has_attribute($attribute) {
//get_object_vars returns an assocative array with all attributes
//Incl. pribate ones as the keys and their current values as the value
$object_vars = get_object_vars($this);
//We dont care about the value, we just want to know if the key exists
//Will return true or false
return array_key_exists($attribute,$object_vars);
}
public function create() {
//This is the create method
global $database;
//DOnt forget your SQL syntax and good habits
//INSERT INTO table (key,key) VALUES ('value','value')
//SIngle-quotes around all values
//Escape all values to prevent sql injection
$query = "INSERT INTO {$this->table_name} (";
$query .= "filename, type, size, caption";
$query .= ") VALUES ('";
$query .= $database->escape_value($this->filename) . "', '";
$query .= $database->escape_value($this->type) . "', '";
$query .= $database->escape_value($this->size) . "', '";
$query .= $database->escape_value($this->caption) . "')";
if($database->query($query)) {
$this->id = $database->insert_id();
return true;
} else {
return false;
}
}
public function update() {
global $database;
//Dont forget your sql good habits
//UPDATE table SET key='value', key='value' WHERE condition
//single quotes around all values
//Escape all values to prevent sql injection
$query = "UPDATE {$this->table_name} SET ";
$query .= "filename='" . $database->escape_value($this->filename) . "', ";
$query .= "type='" . $database->escape_value($this->type) . "', ";
$query .= "size='" . $database->escape_value($this->size) . "', ";
$query .= "caption='" . $database->escape_value($this->caption) . "'";
$query .= " WHERE id=" . $database->escape_value($this->id);
$database->query($query);
return ($database->affected_rows() ==1) ? true : false;
}
public function delete($id=0) {
global $database;
//Dont forget good sql habits
//DELETE FROM table WHERE condition LIMIT 1
//Escape all values to prevent sql injection
//Use limit 1
$query = "DELETE FROM {$this->table_name} ";
$query .="WHERE id=" . $database->escape_value($id);
$query .= " LIMIT 1";
$database ->query($query);
return ($database->affected_rows() ==1) ? true:false;
}
}
?>
He then went onto using find_all() as to get all the contents from the photographs table on the view_photos.php page
$photos = Photograph::find_all();
?>
<?php include_layout_template('admin_header.php'); ?>
<h2>Photographs</h2>
<?php echo output_message($message); ?>
<table class="bordered">
<tr>
<th>Image</th>
<th>Filename</th>
<th>Caption</th>
<th>Size</th>
<th>Type</th>
<th> </th>
</tr>
<?php foreach($photos as $photo): ?>
<tr>
<td><img src="../<?php echo $photo->image_path(); ?>" width="100" /> </td>
<td><?php echo $photo->filename; ?></td>
<td><?php echo $photo->caption; ?></td>
<td><?php echo $photo->size_as_text(); ?></td>
<td><?php echo $photo->type; ?></td>
<td>Delete</td>
</tr>
<?php endforeach; ?>
As you can see he makes a static call to the find_all() method and then loops through the array to list all of the photos from the database using the captured data stored in the photos variable, using all of the variables inside of the class. below is my find_all() method.
public function find_all() {
global $database;
$result = $this->find_by_sql("SELECT * FROM ".$this->table_name);
return $result;
}
when i do the same thing but with an instance of the object Photograph
$photo_object = new Photograph();
$photos = find_all();
If i try and then do the same loop as he does i just get the same result again and again (There are currently 4 entries in the database and i get the exact same entry about 10 times)
Here is my code which results in that output
<?php require_once("../../includes/initialize.php"); ?>
<?php if(!$session->is_logged_in()) { redirect_to("login.php");} ?>
<?php
//This is the class being called
$photo_object = new Photograph();
//Find all photos will return the result from the database. We then need to call the fetch array onit
//$photos = $photo_object->find_all_photos();
$photos = $photo_object->find_all();
?>
<?php include_layout_template('admin_header.php'); ?>
<h2>Photographs: List</h2>
<?php echo output_message($message);?>
<table class="bordered">
<tr>
<th>Image</th>
<th>Filename</th>
<th>Caption</th>
<th>Size</th>
<th>Type</th>
<th> </th>
</tr>
<?php foreach($photos as $photo): ?>
<tr>
<td><img src="<?php echo "../" . $photo_object->image_path() . $photo_object->filename;?>" width="100" /></td>
<td><?php echo $photo_object->filename; ?></td>
<td><?php echo $photo_object->caption; ?></td>
<td><?php echo $photo_object->size_as_text($photo_object->size); ?></td>
<td><?php echo $photo_object->type ?></td>
<td>Delete </td>
</tr>
<?php endforeach; ?>
</table>
<br />
Upload a new photograph
<?php include_layout_template('admin_footer.php'); ?>
The code above outputs
`
Photo Gallery: Admin
Photo Gallery: Admin
Photographs: List
<tr>
<th>Image</th>
<th>Filename</th>
<th>Caption</th>
<th>Size</th>
<th>Type</th>
<th> </th>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td>Delete</td>
</tr>
</table>
<br />
Upload a new photograph
</div>
<div id="footer">Copyright 2015, Ryan Hadley</div>
</body>
</html>
`
Does this method have to be static ? Or am i just not seeing something, I resolved it by writing a new method
public function find_all_photos() {
global $database;
$query = "SELECT * FROM {$this->table_name}";
$result = $database->query($query);
return $result;
}
This works but i dont use any of the variables inside of the class instead i make a call to the photo array which i create in my foreach loop (foreach($photos as $photo)). Which makes the attributes inside of the class seem very pointless. Did i do this the right way ? Or is there something im just not understanding about objects ?
Thankyou in advance for any help i may get
Happy coding

The code as you have it now, passes $object_array into instantiate.
But instantiate is built to accepts only one row retrieved from the resultset.
If you examine $object_array before passing it, you will know more about why you get the undesired results.
public function find_by_sql($sql="") {
global $database;
$result = $database->query($sql);
$object_array = $database->fetch_array($result);
// Examine $object_array:
print '<pre>';
var_dump($object_array);
print '</pre>';
$object = $this->instantiate($object_array);
return $object_array;
}
About the following commented lines:
//while($row = $database->fetch_array($result)) {
//$object_array[] = $this->instantiate($row);
//}
I suggest uncommenting them and examine the $row's:
while( $row = $database->fetch_array($result) ) {
// Examine $row:
print '<pre>';
print_r( $row );
print '</pre>';
//$object_array[] = $this->instantiate($row);
}
About the function instantiate - The way you are using it now, every time it gets called, it sets the properties (id, filename ... etc) of itself.
So the last time this function gets called, the values of the properties of the Photograph instance are the same as the ones from the last $record that has been passed to it.
private function instantiate($record) {
//Could check if $record exists and is an array
//Simple long form approach
//$object = new self;
$this->id= $record['id'];
$this->filename = $record['filename'];
$this->type = $record['type'];
$this->size = $record['size'];
$this->caption = $record['caption'];
}
This is a start to provide you insight about why you see 10 times the same result.
I wrote an example to illustrate how you go about to do what you are looking for (determining from your comments):
/**
* A new class 'Photographs' to 'manage' the collection of photographs:
**/
class Photographs {
protected static $table_name="photographs";
public $photographObjects = array();
function __construct() {
// The constructor runs on creation/instantiation of the 'Photographs' object
print 'Photographs object created...';
}
// Retrieves the data and instantiates Photograph objects:
public function get_photographs() {
global $database;
$sql = "SELECT * FROM ". $this->table_name;
$this->photographObjects = array(); // empty the array before filling it
$result = $database->query($sql);
while( $row = $database->fetch_array( $result ) ) {
$tmpPhotograph = new Photograph();
$tmpPhotograph->id = $row['id'];
$tmpPhotograph->filename = $row['filename'];
// etc etc (or make the 'instantiate' function of the 'Photograph' class public, so you can do:
// $tmpPhotograph->instantiate($row);
// Now add a created and initialized object to your array:
$this->photographObjects[] = $tmpPhotograph;
}
}
// render the photographs:
public function render_photographs() {
if ( count($this->photographObjects) > 0 ) {
// loop through the objects in the photograpsObjects array:
foreach ( $this->photographObjects as $tmpPhotograph ) {
// in this line you can see that public properties (filename), and functions (image_path()) are available:
print '<img src="../' . $tmpPhotograph->image_path() . $tmpPhotograph->filename . '" width="100" />';
}
} else {
// Nothing found, inform the user:
print 'No photographs in array';
}
}
}
To use:
$photographManager = new Photographs();
$photographManager->get_photographs(); // retrieve them
$photographManager->render_photographs(); // output them
or when you want to use your line:
<?php foreach($photos as $photo): ?>
You could do this:
<?php foreach( $photographManager->photographObjects as $photo ): ?>
I hope this clears up some things for you.

Related

Data showing up in the frontend above where it's called

I have a simple class to work with viewing the people who are blacklisted in my web application. Here is the index.php
require_once "../model/ViewBlacklist.php";
// Handling a navigation to the webpage
try {
$viewBlacklist = new ViewBlacklist("view-blacklists.php", "View Blacklists", $navForUser);
} catch (Exception $ex) {
echo $ex->getMessage();
}
Here is the ViewBlacklist class:
class ViewBlacklist {
function __construct(string $page, string $pageTitle, string $navbar) {
if (empty($_POST) && empty($_GET) && empty(file_get_contents("php://input"))) {
$_SESSION["CSRFTOKEN"] = hash("sha512", random_bytes(64));
$csrfToken = $_SESSION["CSRFTOKEN"];
$pageTitle = $pageTitle;
$navForUser = $navbar;
$usernameBlacklist = "<table id='usernameBlacklistTable'>";
$usernameBlacklist .= "<thead><tr><th>Username</th><th>Time Blocked</th><th>When time will expire</th><th>Remove Blacklist?</th></tr></thead>";
$usernameBlacklist .= "<tbody>";
$usernameBlacklist .= $this->getBlacklistedUsernames();
$usernameBlacklist .= "</tbody>";
$usernameBlacklist .= "</table>";
$ipAddressBlacklist = "<table id='ipAddressBlacklistTable'>";
$ipAddressBlacklist .= "<thead><th>Ip Address</th><th>Time Blocked</th><th>When time will expire</th><th>Remove Blacklist?</th></thead>";
$ipAddressBlacklist .= "<tbody>";
$ipAddressBlacklist .= $this->getBlacklistedIps();
$ipAddressBlacklist .= "</tbody>";
$ipAddressBlacklist .= "</table>";
include_once $page;
exit;
}
}
private function getBlacklistedUsernames() : string {
$blacklistedUsernames = "";
$initDB = new DatabaseConfig();
$db = $initDB->start_db();
$sql = "SELECT username, added, allowed FROM blacklisted_users";
$stmt = $db->prepare($sql);
$stmt->execute();
$data = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!empty($data)) {
var_dump($data);
} else {
return "<tr><p class='empty-table-return'>There are no blacklisted usernames</p></tr>";
}
}
private function getBlacklistedIps() : string {
$blacklistedUsernames = "";
$initDB = new DatabaseConfig();
$db = $initDB->start_db();
$sql = "SELECT ip_add, added, allowed FROM blacklisted_ips";
$stmt = $db->prepare($sql);
$stmt->execute();
$data = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!empty($data)) {
var_dump($data);
} else {
return "<tr><p class='empty-table-return'>There are no blacklisted IP addresses</p></tr>";
}
}
}
The problem is, where I'm calling $this->getBlacklistedUsernames(); or $this->getBlacklistedIps() the return from that data (which is currently in the else, because nothing lives in my blacklist tables right now) is going above my tables, so the words There are no blacklisted usernames appear above the entire <table> element contained in the variable $usernameBlacklist and the same for the ip addresses. Here is how it is called in the frontend:
<?php include_once "../header.php"; include_once "../nav.php"; ?>
<?php echo $usernameBlacklist; echo $ipAddressBlacklist; ?>
<?php include_once "../footer.php";
What is making my return from my get...() functions appear above the variable they're concatenated into?
So the problem is, it was actually an HTML validation problem. It turns out that you can't have an element be a direct descendent of a <tr> element that isn't a <td> element. So the reason it was a problem was because my <p> element had no <td> parent surrounding it, so the html validation failure forced the <p> up to the top.

Data not being saved in my database

I hope you are doing great. I'm having a problem where I cannot insert data into my database. There are multiple reasons to why that happens so don't consider it a duplicate question please. I checked my code. For one table it saves the data but for this table. It displays that the same page was not found and no data is saved on the local database. I hope you can help me guys. Thanks in advance. :)
Here are some useful pieces of code:
<?php
include 'Header.php';
?>
<style>
#first {
//margin-right: 100%;
//clear: both;
}
#first > img {
display: inline-block;
//float: left;
}
#first > p {
//float: left;
display: inline-block;
//margin-left: 60px;
//margin-bottom: 120px;
}
</style>
<!-- Post content here -->
<!-- Then cmments below -->
<h1>Comments</h1>
<!--<?php ?>
if (isset($_GET['id'])) {
$id = $_GET['id'];
} elseif (isset($_POST['id'])) {
$id = $_POST['id'];
} else {
echo '<p class="error"> Error has occured</p>';
include 'footer.html';
exit();
}
$db = new Database();
$dbc = $db->getConnection();
$display = 10; //number of records per page
$pages;
if(isset($_GET['p']) ) //already calculated
{
$pages=$_GET['p'];
}
else
{
//use select count() to find the number of users on the DB
$q = "select count(comment_id) from comments";
$r = mysqli_query($dbc, $q);
$row = mysqli_fetch_array($r, MYSQLI_NUM);
$records=$row[0];
if($records > $display ) //calculate the number of pages we will need
$pages=ceil($records/$display);
else
$pages = 1;
}
//now determine where in the database to start
if(isset($_GET['s']) ) //already calculated
$start=$_GET['s'];
else
$start = 0;
//use LIMIT to specify a range of records to select
// for example LIMIT 11,10 will select the 10 records starting from record 11
$q = "select * from users order by $orderby LIMIT $start, $display";
$r = mysqli_query($dbc, $q);
/*if ($r)
{*/
$result = mysql_query("SELECT * FROM comments WHERE video_id= '" + + "'");
//0 should be the current post's id
while($row = mysql_fetch_object($result))
{
?>
<div class="comment">
By: <!--<?php /* echo $row->author; //Or similar in your table ?>
<p>
<?php echo $row->body; ?>
</p>
</div>
<?php
/*} */
?>*/-->
<h1>Leave a comment:</h1>
<form action="Comment.php" method="post">
<!-- Here the shit they must fill out -->
<input type="text" name="comment" value="" />
<input type="hidden" name="submitted" value="TRUE" />
<input type="submit" name="submit" value="Insert"/>
</form>';
<?php
if (isset($_POST['submitted'])) {
$comment = '';
$errors = array();
if (empty($_POST['comment']))
$errors[] = 'You should enter a comment to be saved';
else
$comment = trim($_POST['comment']);
if (empty($errors)) {
include 'Comments_1.php';
$comment_2 = new Comments();
$errors = $comment_2->isValid();
$comment_2->Comment = trim($_POST['comment']);
$comment_2->UserName = hamed871;
$comment_2->Video_Id = 1;
if ($comment_2->save()) {
echo '<div class="div_1"><div id="div_2">' .
'<h1>Thank you</h1><p> your comment has been'
. ' posted successfully</p></div></div>';
}
}
//First check if everything is filled in
/* if(/*some statements *//* )
{
//Do a mysql_real_escape_string() to all fields
//Then insert comment
mysql_query("INSERT INTO comments VALUES ($author,$postid,$body,$etc)");
}
else
{
die("Fill out everything please. Mkay.");
}
?>
id (auto incremented)
name
email
text
datetime
approved--> */
}
?>
<!--echo '--><div id="first">
<img src="http://www.extremetech.com/wp-content/uploads/2013/11/emp-blast.jpg?type=square" height="42" width="42"/>
<p>hamed1</p>
</div><!--';-->
<dl>
<dt>comment1</dt>
<dd>reply1</dd>
<dd>reply2</dd>
</dl>
<!--//}
/*else
{
}*/
?>-->
<?php
include 'Footer.php';
?>
My Comment class:
<?php
include_once "DBConn.php";
class Comments extends DBConn {
private $tableName = 'Comments';
//attributes to represent table columns
public $comment_Id = 0;
public $Comment;
public $UserName;
public $Video_Id;
public $Date_Time;
public function save() {
if ($this->getDBConnection()) {
//escape any special characters
$this->Comment = mysqli_real_escape_string($this->dbc, $this->Comment);
$this->UserName = mysqli_real_escape_string($this->dbc, $this->UserName);
$this->Video_Id = mysqli_real_escape_string($this->dbc, $this->Video_Id);
if ($this->comment_Id == null) {
$q = 'INSERT INTO comments(Comment, User_Id, Video_Id, Date_Time) values' .
"('" . $this->Comment . "','" . $this->User_Id . "','" . $this->Video_Id . "',NOW()')";
} else {
$q = "update Comments set Comment='" . $this->Comment . "', Date_Time='" . NOW() ."'";
}
// $q = "call SaveUser2($this->userId,'$this->firstName','$this->lastName','$this->email','$this->password')";
$r = mysqli_query($this->dbc, $q);
if (!$r) {
$this->displayError($q);
return false;
}
return true;
} else {
echo '<p class="error">Could not connect to database</p>';
return false;
}
return true;
}
//end of function
public function get($video_id) {
if ($this->getDBConnection()) {
$q = "SELECT Comment, Date_Time, UserName FROM Comments WHERE Video='" . $userName."' order by time_stamp";
$r = mysqli_query($this->dbc, $q);
if ($r) {
$row = mysqli_fetch_array($r);
$this->Comment = mysqli_real_escape_string($this->dbc, $this->Comment);
return true;
}
else
$this->displayError($q);
}
else
echo '<p class="error">Could not connect to database</p>';
return false;
}
public function isValid() {
//declare array to hold any errors messages
$errors = array();
if (empty($this->Comment))
$errors[] = 'You should enter a comment to be saved';
return $errors;
}
}
?>
Output show when I click insert button:
Not Found
The requested URL /IndividualProject/Comment.php was not found on this server.
Apache/2.4.17 (Win64) PHP/5.6.16 Server at localhost Port 80
I encountered this kind of issue when working on a staging site because webhosting may have different kinds of restrictions and strict. Now what I did is changing the filename for example:
Class name should match the filename coz it's case sensitive.
Comment.php
class Comment extends DBConn {
function __construct () {
parent::__construct ();
}
//code here..
}

Lynda - PHP Beyond the Basics - Database error when uploading photo

I searched before writing this question but didn't think I would find a response because my issue is SO specific.
Anyway, I have been following the PHP Beyond the Basics course on Lynda.com by Kevin Skoglund and have run into a snag when it comes to uploading photos to the database (MySQL). This is my first real foray into OOP and have been brought to a stretching halt. I've been looking at my files for a over week trying my best to sort out the issue with no luck.
Oddly I have tried using the exercise files directly on my local machine and I'm getting the same error (with my information like database creds and directory names).
Basically my problem is that when I try to upload a photo it gets moved from the temp directory to the images directory but never makes its way to the database. I get the 'database query failed' message when it posts and the photograph table in mysql remains empty. I see where the error is coming from ( inside database.php confirm_query() ) but have no inclination as to what the issue could be. I know I am able to communicate with the database because just before moving onto creating the photograph class/table I was able to add users to the user table in the database.
Below are my files. Im adding the three that I believe relate to this issue but will zip the whole project up and upload it to dropbox as well. Any help/insight would be more than greatly appreciated!!
*please note that I have put the functions from the databaseObject into the photograph class
photo_upload.php:
<?php
require_once('../../includes/initialize.php');
if (!$session->is_logged_in()) {
redirect_to("login.php");
}
$max_file_size = 1048576; //expressed in bytes
// 10240 = 10kb
// 102400 = 100kb
//1048576 = 1mb
//10485760 = 1mb
$message = "";
if (isset($_POST['submit'])) {
$photo = new Photograph();
$photo->caption = $_POST['caption'];
$photo->attach_file($_FILES['file_upload']);
if ($photo->save()) {
//success
$message = "Photograph uploaded successfully";
} else {
//failure
$message = join("<br>", $photo->errors);
}
}
include_layout_template('admin_header.php');
?>
<h2>Photo Upload</h2>
<?php echo output_message($message); ?>
<form action="photo_upload.php" enctype="multipart/form-data" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max_file_size ?>">
<p><input type="file" name="file_upload"></p>
<p>Caption: <input type="text" name="caption" value=""></p>
<input type="submit" name="submit" value="upload">
</form>
<?php include_layout_template('admin_footer.php'); ?>
Photograph.php:
<?php
// If it's going to need the database, then it's
// probably smart to require it before we start.
require_once(LIB_PATH.DS.'database.php');
class Photograph extends DatabaseObject {
protected static $table_name="photographs";
protected static $db_fields=array('id', 'filename', 'type', 'size', 'caption');
public $id;
public $filename;
public $type;
public $size;
public $caption;
private $temp_path;
protected $upload_dir="images";
public $errors=array();
protected $upload_errors = array(
// http://www.php.net/manual/en/features.file-upload.errors.php
UPLOAD_ERR_OK => "No errors.",
UPLOAD_ERR_INI_SIZE => "Larger than upload_max_filesize.",
UPLOAD_ERR_FORM_SIZE => "Larger than form MAX_FILE_SIZE.",
UPLOAD_ERR_PARTIAL => "Partial upload.",
UPLOAD_ERR_NO_FILE => "No file.",
UPLOAD_ERR_NO_TMP_DIR => "No temporary directory.",
UPLOAD_ERR_CANT_WRITE => "Can't write to disk.",
UPLOAD_ERR_EXTENSION => "File upload stopped by extension."
);
// Pass in $_FILE(['uploaded_file']) as an argument
public function attach_file($file) {
// Perform error checking on the form parameters
if(!$file || empty($file) || !is_array($file)) {
// error: nothing uploaded or wrong argument usage
$this->errors[] = "No file was uploaded.";
return false;
} elseif($file['error'] != 0) {
// error: report what PHP says went wrong
$this->errors[] = $this->upload_errors[$file['error']];
return false;
} else {
// Set object attributes to the form parameters.
$this->temp_path = $file['tmp_name'];
$this->filename = basename($file['name']);
$this->type = $file['type'];
$this->size = $file['size'];
// Don't worry about saving anything to the database yet.
return true;
}
}
public function save() {
// A new record won't have an id yet.
if(isset($this->id)) {
// Really just to update the caption
$this->update();
} else {
// Make sure there are no errors
// Can't save if there are pre-existing errors
if(!empty($this->errors)) { return false; }
// Make sure the caption is not too long for the DB
if(strlen($this->caption) > 255) {
$this->errors[] = "The caption can only be 255 characters long.";
return false;
}
// Can't save without filename and temp location
if(empty($this->filename) || empty($this->temp_path)) {
$this->errors[] = "The file location was not available.";
return false;
}
// Determine the target_path
$target_path = SITE_ROOT .DS. 'public' .DS. $this->upload_dir .DS. $this->filename;
// Make sure a file doesn't already exist in the target location
if(file_exists($target_path)) {
$this->errors[] = "The file {$this->filename} already exists.";
return false;
}
// Attempt to move the file
if(move_uploaded_file($this->temp_path, $target_path)) {
// Success
// Save a corresponding entry to the database
if($this->create()) {
// We are done with temp_path, the file isn't there anymore
unset($this->temp_path);
return true;
}
} else {
// File was not moved.
$this->errors[] = "The file upload failed, possibly due to incorrect permissions on the upload folder.";
return false;
}
}
}
// Common Database Methods
public static function find_all() {
return self::find_by_sql("SELECT * FROM ".self::$table_name);
}
public static function find_by_id($id=0) {
$result_array = self::find_by_sql("SELECT * FROM ".self::$table_name." WHERE id={$id} LIMIT 1");
return !empty($result_array) ? array_shift($result_array) : false;
}
public static function find_by_sql($sql="") {
global $database;
$result_set = $database->query($sql);
$object_array = array();
while ($row = $database->fetch_array($result_set)) {
$object_array[] = self::instantiate($row);
}
return $object_array;
}
private static function instantiate($record) {
// Could check that $record exists and is an array
$object = new self;
// Simple, long-form approach:
// $object->id = $record['id'];
// $object->username = $record['username'];
// $object->password = $record['password'];
// $object->first_name = $record['first_name'];
// $object->last_name = $record['last_name'];
// More dynamic, short-form approach:
foreach($record as $attribute=>$value){
if($object->has_attribute($attribute)) {
$object->$attribute = $value;
}
}
return $object;
}
private function has_attribute($attribute) {
// We don't care about the value, we just want to know if the key exists
// Will return true or false
return array_key_exists($attribute, $this->attributes());
}
protected function attributes() {
// return an array of attribute names and their values
$attributes = array();
foreach(self::$db_fields as $field) {
if(property_exists($this, $field)) {
$attributes[$field] = $this->$field;
}
}
return $attributes;
}
protected function sanitized_attributes() {
global $database;
$clean_attributes = array();
// sanitize the values before submitting
// Note: does not alter the actual value of each attribute
foreach($this->attributes() as $key => $value){
$clean_attributes[$key] = $database->escape_value($value);
}
return $clean_attributes;
}
// replaced with a custom save()
// public function save() {
// // A new record won't have an id yet.
// return isset($this->id) ? $this->update() : $this->create();
// }
public function create() {
global $database;
// Don't forget your SQL syntax and good habits:
// - INSERT INTO table (key, key) VALUES ('value', 'value')
// - single-quotes around all values
// - escape all values to prevent SQL injection
$attributes = $this->sanitized_attributes();
$sql = "INSERT INTO ".self::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUES ('";
$sql .= join("', '", array_values($attributes));
$sql .= "')";
if($database->query($sql)) {
$this->id = $database->insert_id();
return true;
} else {
return false;
}
}
public function update() {
global $database;
// Don't forget your SQL syntax and good habits:
// - UPDATE table SET key='value', key='value' WHERE condition
// - single-quotes around all values
// - escape all values to prevent SQL injection
$attributes = $this->sanitized_attributes();
$attribute_pairs = array();
foreach($attributes as $key => $value) {
$attribute_pairs[] = "{$key}='{$value}'";
}
$sql = "UPDATE ".self::$table_name." SET ";
$sql .= join(", ", $attribute_pairs);
$sql .= " WHERE id=". $database->escape_value($this->id);
$database->query($sql);
return ($database->affected_rows() == 1) ? true : false;
}
public function delete() {
global $database;
// Don't forget your SQL syntax and good habits:
// - DELETE FROM table WHERE condition LIMIT 1
// - escape all values to prevent SQL injection
// - use LIMIT 1
$sql = "DELETE FROM ".self::$table_name;
$sql .= " WHERE id=". $database->escape_value($this->id);
$sql .= " LIMIT 1";
$database->query($sql);
return ($database->affected_rows() == 1) ? true : false;
// NB: After deleting, the instance of User still
// exists, even though the database entry does not.
// This can be useful, as in:
// echo $user->first_name . " was deleted";
// but, for example, we can't call $user->update()
// after calling $user->delete().
}
}
?>
database.php:
<?php
require_once("config.php");
class MySQLDatabase {
//Step #1 open connection
private $connection;
function __construct() {//once you create an instance of this class it will automatically create the connection
$this->open_connection();
}
public function open_connection(){
$this->connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
//Test the connection
if(mysqli_connect_errno()){//use errno because error returns an empty string if succesful
die('Database connection failed: '. mysqli_connect_error().
'('.mysqli_connect_errno().')');
}
}
//Step #2 preform database query
public function query($sql){
$result = mysqli_query($this->connection, $sql);
$this->confirm_query($result);
return $result;
}
private function confirm_query($result){
if(!$result){ //this is a check to make sure the query worked
die('Database query failed');
}
}
public function escape_value($string){
$escaped_string = mysqli_real_escape_string($this->connection, $string);
return $escaped_string;
}
//database neutral functions
//this is our database adapter which is called for mysql
public function fetch_array($result_set){
return mysqli_fetch_array($result_set);
}
public function num_rows($result_set) {
return mysqli_num_rows($result_set);
}
public function insert_id(){
//get the last id inserted over the current connection
return mysqli_insert_id($this->connection);
}
public function affected_rows(){
return mysqli_affected_rows($this->connection);
}
//Step #4 close connection
public function close_connection() {
if(isset($this->connection)){
mysqli_close($this->connection);
unset($this->connection);
}
}
}
$database = new MySQLDatabase();
?>
https://www.dropbox.com/s/oqdi2dz2mbkuwzz/photo_gallery.zip?dl=0
After more digging around I have concluded that my problem was not with my code. There was an sql setting that would not allow me to enter and empty string sqlmode=STRICT_TRANS_TABLES. Thank you maxhb for pointing me in the right direction!!
What I did end up doing to solve this issue was create a my.conf file to change the default settings (im running mysql 5.7.9 on mac osx 10.11 btw). What was weird was that it only worked if I put this file in two locations they are .my.cnf and /etc/mysql/my.cnf with the following text:
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION

Mysql INSERT statement FAILING when POSTING large array

I've been searching the internet and "pulling my hair out" for days over this. It works fine on my XAMPP localhost and was working fine on my online testing server until I updated the PHP version and had to rewrite the code due to deprecated syntax.
Basically, I'm making a backend database for photography clients. One of the tables is designed to store image information. I haven't tried to store an actual image (BLOB of some sorts), I'm just looking to store "what and where".
What seems to be happening is if I try entering the contents of a shoot directory with several hundred images, when I hit input the screen changes, then instead of telling me how many were entered, it goes to a "418 unused" page saying
The server encountered an internal error or misconfiguration and was unable to complete your request.
I've been trying to narrow down which buffers to increase or variables like "max_allowed_packet", "max_input_vars"... still no luck. I've even tried comparing the phpinfo between the two servers to find out why one works and the other doesn't...
Here's what I'm doing... the listpage
<?php
// set page headers
$page_title = "Enter Images into Database";
include_once 'auth.php';
// get database connection
include_once 'config/fpaddb.php';
include_once 'objects/clients.php';
include_once 'objects/photoshoots.php';
include_once 'objects/images.php';
$database = new Database();
$db = $database->getConnection();
$colname_chk_Images = "-1";
if (isset($_GET['ShootId'])) {
$colname_chk_Images = $_GET['ShootId'];
}
$colname1_chk_Images = "NULL";
if (isset($_GET['ShootFolder'])) {
$colname1_chk_Images = $_GET['ShootFolder'];
}
$colname_get_Images = "-1";
if (isset($_SESSION['cID'])) {
$colname_get_Images = $_SESSION['cID'];
}
$entered=0; //check for already entered images
?>
<?php
$dirname=$_SESSION['cIFolder'];
$Clogin=$_SESSION['Clogin'];
$ClientID=$_SESSION['cID'];
$_SESSION['CURR_CLIENT_ID'] = $ClientID;
$maindir=$_GET['ShootFolder'];
$ShootId=$_GET['ShootId'];
$dir=$_SERVER['DOCUMENT_ROOT'].dirname($_SERVER['PHP_SELF'])."protect/clientfolders/".$Clogin."/users/".$Clogin."/images/".$maindir;
$_SESSION['dir']=$dir;
$dir2="/protect/clientfolders/".$Clogin."/users/".$Clogin."/images/".$maindir;
$dirt= "/phpThumb-master/";
$dirn= dirname($_SERVER['PHP_SELF']);
$filesArray=array_map('basename', glob($dir."/*.jpg"));
$lightbox_data= "FPAD_Lightbox";
$thumb = "$dir2/";
$notThumb = "$dir2/";
$ic = count($filesArray);
$_SESSION['SESS_TOTNUM'] = $ic;
$_SESSION['sID'] = $ShootId;
$sID = $_SESSION['sID'];
include_once 'header_a.php';
?>
<div class="container">
<?php
echo $_SESSION['SESS_TOTNUM']." images found ";
echo "for Shoot ID#: ".$_SESSION['sID']."<br>";
echo "*Note* - if input boxes come up GREEN, then images are already loaded into the database";
?>
<p>
<?php
$images1 = new Image($db);
$images1->ShootId = $colname_chk_Images;
$images1->directory = $colname1_chk_Images;
$images1->ClientID = $colname_get_Images;
$chk_Images = $images1->checkImages();
$get_Images = $images1->getImages();
$Images = array();
while ($row_get_Images = $get_Images->fetch(PDO::FETCH_ASSOC))
{
$Images[] = $row_get_Images['image_name'];
}
?></p>
<form method="POST" name="form1" id="form1" action="input.php">
<table id="clientshoots" class="table table-condensed table-bordered table-small">
<tr>
<th>image_id</th>
<th>image_name</th>
<th>image_path</th>
<th>image_path_root</th>
<th>image_size</th>
<th>directory</th>
<th width="auto">ShootId</th>
<th width="auto">ClientID</th>
<th>ClientName</th>
<th>login</th>
</tr>
<?php $ic=0;
for($i=0;$i<count($filesArray);$i++) {
$fileinfo = $filesArray[$i];
$fname=$dir."/".$fileinfo;
$fname2=$dir2."/".$fileinfo;
$size = filesize($fname);
$atime = date("F d, Y H:i:s", fileatime($fname));
$mtime= date("F d, Y H:i:s", filemtime($fname));
$perms=decoct(fileperms($fname) & 0777);
$type=filetype($fname);
$pth=realpath($fname);
$name=basename($fname);
$dn=dirname($fname2);
if (in_array($fileinfo, $Images)) {
$entered=1;
echo "<style type=\"text/css\">\n";
echo "input {\n";
echo "background-color:#00FF33;\n";
echo "}\n";
echo "</style>";
}
?>
<tr>
<td> </td>
<td><input type="text" name="image_name[]" value="<?php echo $fileinfo; ?>" readonly/></td>
<td><input type="text" name="image_path[]" value="<?php echo $dir; ?>" readonly/></td>
<td><input type="text" name="image_path_root[]" value="<?php echo $dir2; ?>" readonly/></td>
<td><input type="number" name="image_size[]" value="<?php echo $size; ?>" readonly/></td>
<td><input type="text" name="directory[]" value="<?php echo $maindir; ?>" readonly/></td>
<td><input type="number" name="ShootId[]" value="<?php echo $ShootId; ?>" readonly/></td>
<td><input type="number" name="ClientID[]" value="<?php echo $ClientID; ?>" readonly/></td>
<td><input type="text" name="ClientName[]" value="<?php echo $_SESSION['cName']; ?>" readonly/></td>
<td><input type="text" name="login[]" value="<?php echo $Clogin; ?>" readonly/></td>
</tr>
<?php next($filesArray);
$ic=$ic+1;
}
$_SESSION['SESS_IC'] = $ic;?>
</table>
<?php if ($entered == 1){
echo "Return";
} else {
echo "<input class=\"btn-primary\" style=\"background-color:\" id=\"Insert records\" type=\"submit\" value=\"Insert records\">";
}?>
<input type="hidden" name="MM_insert" value="form1">
<input type="hidden" name="sID" value="<?php echo $sID; ?>">
</form>
</div>
<br>
<!-- /container -->
<?php include 'footer_b.php'; ?>
and then the input.php page...
<?php
// set page headers
$page_title = "Enter Images into Database";
include_once 'auth.php';
// get database connection
include_once 'config/fpaddb.php';
include_once 'objects/clients.php';
include_once 'objects/photoshoots.php';
include_once 'objects/images.php';
include_once 'objects/ratings.php';
$database = new Database();
$db = $database->getConnection();
$sID = $_SESSION['sID'];
$ic = $_SESSION['SESS_IC'];
$ma = $_SESSION['SESS_CLIENT_MULTI'];
$gn = $_SESSION['SESS_CLIENT_GRPNO'];
$cID = $_SESSION['cID'];
$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
$editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}
//Function to sanitize values received from the form. Prevents SQL injection
function clean($str) {
$str = filter_var(($str), FILTER_SANITIZE_STRING);
return ($str);
}
$image1 = new Image($db);
$count = count($_POST['image_name']);
$fileinfo = clean($_POST['image_name']);
//Check for duplicates
if($fileinfo != '') {
for($i=0;$i<$count;$i++) {
$fileinfo = clean($_POST['image_name'][$i]);
//echo $fileinfo;
$image1->image_name = $fileinfo;
$result = $image1->check4Dup();
if($result) {
if(count($result) > 0) {
$errmsg_arr[] = 'Image already entered into Database';
$errflag = true;
}
$result = NULL;
}
else {
die($e->getMessage());
}
next($count);
}
}
$image1->ic = $ic;
$num = $image1->create();
$colname_newImages = "-1";
if (isset($sID)) {
$colname_newImages = $sID;
}
$image1->ShootId = $sID;
$newImages = $image1->countOneShoot();
$row_newImages = $newImages->fetch(PDO::FETCH_ASSOC);
$totalRows_newImages = $newImages->rowCount();
$ic2 = $totalRows_newImages;
$_SESSION['SESS_TOTNUM_ENT'] = $ic2;
header("Location: rs_images.php");
include_once 'header_a.php';
?>
<div class="container">
<?php
echo "Success! Number of images entered is ".$ic2; ?>
<br><br>
<p><input name="Verify" type="button" value="Verify Inputs" onclick="MM_goToURL('parent','rs_images.php');return document.MM_returnValue"/></p>
</div>
<?php include 'footer_b.php'; ?>
And the Class file...
<?php
class Image{
// database connection and table name
private $dbh;
private $table_name = "images";
// object properties
public $image_id;
public $image_name;
public $image_path;
public $image_path_root;
public $image_size;
public $directory;
public $ShootId;
public $ClientID;
public $ClientName;
public $login;
public $ic;
public function __construct($db){
$this->dbh = $db;
}
// Clean Function
function clean($str){
$str = filter_var(($str), FILTER_SANITIZE_STRING);
return ($str);
}
// test function
function test(){
$ic = $this->ic;
$i=1;
$j=1;
foreach ($_POST['image_name'] as $row=>$iname)
{
$image_name = clean($iname);
$image_path = clean($_POST['image_path'][$row]);
$image_path_root = clean($_POST['image_path_root'][$row]);
$image_size = clean($_POST['image_size'][$row]);
$directory = clean($_POST['directory'][$row]);
$ShootId = clean($_POST['ShootId'][$row]);
$ClientID = clean($_POST['ClientID'][$row]);
$ClientName = clean($_POST['ClientName'][$row]);
$login = clean($_POST['login'][$row]);
$Clogin = $login."');";
$i=$i+1;
$j=$j+1;
$qry1st = "INSERT INTO `images` (image_name, image_path, image_path_root, image_size, directory, ShootId, ClientID, ClientName, login) VALUES ";
$sql_array = "('".$image_name."', '".$image_path."', '".$image_path_root."', ".$image_size.", '".$directory."', ".$ShootId.", ".$ClientID.", '".$ClientName."', '".$Clogin;
//$stmt = $this->dbh->prepare($qry1st.$sql_array);
//$stmt->execute();
echo $qry1st.$sql_array;
}
}
// create function
function create(){
$ic = $this->ic;
$qry1st = "INSERT INTO `images` (image_name, image_path, image_path_root, image_size, directory, ShootId, ClientID, ClientName, login) VALUES ";
$sql_array = array(); // This is where we'll queue up the rows
$queue_num = 50; // How many rows should be queued at once?
$i=1;
foreach ($_POST['image_name'] as $row=>$iname)
{
$image_name = clean($iname);
$image_path = clean($_POST['image_path'][$row]);
$image_path_root = clean($_POST['image_path_root'][$row]);
$image_size = clean($_POST['image_size'][$row]);
$directory = clean($_POST['directory'][$row]);
$ShootId = clean($_POST['ShootId'][$row]);
$ClientID = clean($_POST['ClientID'][$row]);
$ClientName = clean($_POST['ClientName'][$row]);
$login = clean($_POST['login'][$row]);
if ($i==($_SESSION['SESS_TOTNUM'])) {
$login_term = $login."');";
}
else
{
$login_term = $login."')";
$i=$i+1;
}
$sql_array[] = "('".$image_name."', '".$image_path."', '".$image_path_root."', ".$image_size.", '".$directory."', ".$ShootId.", ".$ClientID.", '".$ClientName."', '".$login_term;
// Add a new entry to the queue
$c=0;
if (count($sql_array) >= $queue_num)
{ // Reached the queue limit
$addImages = $this->dbh->query($qry1st . implode(', ', $sql_array)); // Insert those that are queued up
$addImages->execute();
$sql_array = array(); // Erase the queue
}//End if
}//end foreach
if (count($sql_array) > 0) // There are rows left over
{
$addImages = $this->dbh->query($qry1st . implode(', ', $sql_array));
$addImages->execute();
}
}
function checkImages(){
$query_chk_Images = "SELECT images.image_name FROM images WHERE ShootId = ? AND directory = ?";
$chk_Images = $this->dbh->prepare ($query_chk_Images);
$chk_Images->bindValue(1, $this->ShootId);
$chk_Images->bindValue(2, $this->directory);
$chk_Images->execute();
return $chk_Images;
}
// create function
function getImages(){
$query_get_Images = "SELECT * FROM images WHERE ClientID = ? ORDER BY image_name ASC";
$get_Images = $this->dbh->prepare ($query_get_Images);
$get_Images->bindValue(1, $this->ClientID);
$get_Images->execute();
return $get_Images;
}
// create function
function getImageID(){
$query_rsImageID = "SELECT * FROM images WHERE ShootId = ? ORDER BY image_id ASC";
$rsImageID = $this->dbh->prepare($query_rsImageID);
$rsImageID->bindValue(1, $this->ShootId);
$rsImageID->execute();
return $rsImageID;
}
// create function
function get_image_id(){
$q = "SELECT image_id FROM images WHERE ShootId = ? ORDER BY image_id ASC";
$stmt = $this->dbh->prepare($q);
$stmt->bindValue(1, $this->ShootId);
$stmt->execute();
return $stmt;
}
// create function
function countOneShoot(){
$query_newImages = "SELECT * FROM images WHERE ShootId = ?";
$newImages = $this->dbh->prepare($query_newImages);
$newImages->bindValue(1, $this->ShootId);
$newImages->execute();
return $newImages;
}
// create function
function check4Dup(){
$qry = "SELECT * FROM `images` WHERE image_name = ?";
$result = $this->dbh->prepare($qry);
$result->bindValue(1, $this->image_name);
$result->execute();
return $result;
}
}
I've striped out all the extra stuff I've tried, like entering the info one record at a time, binding the Values with colon prefixed field names instead of the ?'s. I've tried different loops. I think it comes down to trying to push too much through one query... but then why does it work on XAMPP and why was it working fine with PHP 5.2?
I appreciate any light that can be shed on this. This is my first ever post with regards to PHP, MySQL or anything site related, I've been learning this stuff as I go and had it 90% completed and debugged and when I put it online to do some real testing with the actual directories and client folders that's when I found out that between PHP 5.4 and 5.2, there have been a number of changes and I found myself rewriting almost every line to move up to either MySQLi or PDO/OOP. After doing a lot searching around the internet I've opted for the OOP approach and still need to rewrite even more of the code above to clean things up a ton, but right now I'm troubleshooting the INSERT failure which I have not been able to solve on my own or with the help of all the forums, posts and blogs I've read to date.

PHP logging out

I am doing the Lynda.com learning PHP 2 videos and have run into a problem, in that the instructor seems to have neglected to tell us one of the steps he does in the video. I have uploaded the relevant video here http://www.youtube.com/watch?v=fFKgAa7RAjo but will also describe the problem. At 6:40 of the video, after logging in to our application, he arrives at public/admin/index.php which has two links on it. one link allows him to "view log file" which takes him to public/admin/logfile.php and the other link allows him to log out. He doesn't tell us how to make these links. I can obviously make a link to view logfile
View Logfile
but I don't know how to make the link that will log me out, because that will obviously involve some PHP.
I have included below the login.php file, the index.php file (it's redirected to index.php after logging in) and the functions.php file. Do you know how I would logout from this?
This is the login.php file
<?php
require_once("../../includes/initialize.php");
if($session->is_logged_in()){
redirect_to("index.php");
}
//Remember to give your form's submit tag a name="submit" attribute
if (isset($_POST['submit'])) {//Form has been submitted.
$username = trim($_POST['username']);
$password = trim($_POST['password']);
//Check database to see if username/password exist
$found_user = User::authenticate($username, $password);
if ($found_user) {
$session->login($found_user);
log_action('Login', "{$found_user->username} logged in.");
redirect_to("index.php");
} else {
//username/password combo was not found in the database
$message = "Username/password combination incorrect.";
}
} else {//Form has not been submitted.
$username = "";
$password = "";
}
?>
<?php include_layout_template('admin_header.php'); ?>
<h2>Staff Login</h2>
<?php echo output_message($message); ?>
<form action="login.php" method="post">
<table>
<tr>
<td>Username:</td>
<td>
<input type="text" name="username" maxlength="30" value="<?php
echo htmlentities($username); ?>" />
</td>
</tr>
<tr>
<td>Password:</td>
<td>
<input type="password" name="password" maxlength="30" value="<?php
echo htmlentities($password); ?>" />
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" name="submit" value="login" />
</td>
</tr>
</table>
</form>
</div>
<?php include_layout_template('admin_footer.php'); ?>
Functions.php
<?php
function strip_zeros_from_date( $marked_string=""){
//first remove the marked zeros
$no_zeros = str_replace('*0', '', $marked_string);
//then remove any remaining marks
$cleaned_string = str_replace('*', '', $no_zeros);
return $cleaned_string;
}
function redirect_to( $location= NULL) {
if($location != NULL) {
header("Location: {$location}");
exit;
}
}
function output_message($message=""){
if (!empty($message)) {
return "<p class=\"message\">{$message}</p>";
} else {
return "";
}
}
function __autoload($class_name) {
$class_name = strtolower($class_name);
$path = LIB_PATH.DS."{$class_name}.php";
if(file_exists($path)){
require_once($path);
} else {
die("The file {$class_name}.php could not be found.");
}
}
function include_layout_template($template=""){
include(SITE_ROOT.DS.'public'.DS.'layouts'.DS.$template);
}
function log_action($action, $message=""){
$logfile = SITE_ROOT.DS.'logs'.DS.'log.txt';
$new = file_exists($logfile) ? false : true;
if($handle = fopen($logfile, 'a')) { //apppend
$timestamp = strftime("%Y-%m-%d %H:%M:%S", time());
$content = "{$timestamp} | {$action}: {$message}\n";
fwrite($handle,$content);
fclose($handle);
if($new) {chmod($logfile, 0755); }
} else {
echo "Could not open log file for writing.";
}
}
?>
Index.php
<?php
require_once('../../includes/initialize.php');
if (!$session->is_logged_in()) { redirect_to("login.php"); }
?>
<?php include_layout_template('admin_header.php'); ?>
<h2>Menu</h2>
</div>
<?php include_layout_template('admin_footer.php'); ?>
Update
Initialize.php
<?php
//Directory_separator is a PHP pre-defined constant
// (\ for windows, / for Unix)
defined('DS') ? null : define('DS', DIRECTORY_SEPARATOR);
defined('SITE_ROOT') ? null :
define('SITE_ROOT', DS.'hsphere'.DS.'local'.DS.'home'.DS.'c263430'.DS.'quoralist.com');
// define('SITE_ROOT', realpath(dirname(__FILE__).'/../'));
//echo SITE_ROOT."<br/>";
defined('LIB_PATH') ? null : define('LIB_PATH', SITE_ROOT.DS.'includes');
// die(LIB_PATH);
//echo LIB_PATH."<br/>";
require_once(LIB_PATH.DS."config.php");
require_once(LIB_PATH.DS."functions.php");
require_once(LIB_PATH.DS."session.php");
require_once(LIB_PATH.DS."database.php");
require_once(LIB_PATH.DS."database_object.php");
require_once(LIB_PATH.DS."user.php");
//echo("You die here");
?>
User.php
<?php
require_once(LIB_PATH.DS.'database.php');
class User extends DatabaseObject{
protected static $table_name="users";
public $id;
public $username;
public $password;
public $first_name;
public $last_name;
public function full_name() {
if(isset($this->first_name) && isset($this->last_name)) {
return $this->first_name . " " . $this->last_name;
} else {
return "";
}
}
public static function authenticate($username="",$password="") {
global $database;
$username = $database->escape_value($username);
$password = $database->escape_value($password);
$sql = "SELECT * FROM users ";
$sql .= "WHERE username = '{$username}' ";
$sql .= "AND password = '{$password}' ";
$sql .= "LIMIT 1";
$result_array = self::find_by_sql($sql);
return !empty($result_array) ? array_shift($result_array) : false;
}
//common database methods
public static function find_all(){
return self::find_by_sql("SELECT * FROM ".self::$table_name);
}
public static function find_by_id($id=0) {
global $database;
$result_array = self::find_by_sql("SELECT * FROM ".self::$table_name." WHERE id={$id} LIMIT 1");
return !empty($result_array) ? array_shift($result_array) : false;
}
public static function find_by_sql($sql=""){
global $database;
$result_set = $database->query($sql);
$object_array = array();
while ($row = $database->fetch_array($result_set)) {
$object_array[] = self::instantiate($row);
}
return $object_array;
}
private static function instantiate($record){
$object = new self;
//$object->id = $record['id'];
//$object->username = $record['username'];
//$object->password = $record['password'];
//$object->first_name = $record['first_name'];
//$object->last_name = $record['last_name'];
foreach($record as $attribute=>$value) {
if($object->has_attribute($attribute)) {
$object->$attribute = $value;
}
}
return $object;
}
private function has_attribute($attribute) {
$object_vars = get_object_vars($this);
return array_key_exists($attribute, $object_vars);
}
}
?>
Session.php
<?php
class Session {
private $logged_in=false;
public $user_id;
function __construct() {
session_start();
$this->check_login();
if($this->logged_in){
//actions to take right away if user is logged in
} else {
//actions to take right away if user is not logged in
}
}
public function is_logged_in() {
return $this->logged_in;
}
public function login($user) {
//database should find user based on username/password
if($user){
$this->user_id = $_SESSION['user_id'] = $user->id;
$this->logged_in = true;
}
}
public function logout(){
unset($_SESSION['user_id']);
unset($this->user_id);
$this->logged_in = false;
}
private function check_login(){
if(isset($_SESSION['user_id'])){
$this->user_id = $_SESSION['user_id'];
$this->logged_in = true;
} else {
unset($this->user_id);
$this->logged_in = false;
}
}
}
$session = new Session();
?>
<?php
session_start();
session_destroy();
?>
That should destroy all variables stored in the session. It is really primitive logging out, but it should work. After you do that just redirect to "index.php" or whatever page you want.

Categories