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
Related
I am trying to store image name along with other data in the database but not being able to. nothing is inserted in the database. but the image is uploaded in the directory when i close the brace } before db config. but i got call to an undefined function upload() when i close the function brace } after inserting. here is the code:
$imagesub = isset( $_FILES['image'] );
if ( $imagesub )
{
$output=upload();
}
return $output;
function upload()
{
include_once "class.php";
$uploader = new Uploader( "image" );
$uploader->saveIn("images");
$fileUploaded = $uploader->save();
$db = new mysqli("localhost", "root","","learndb");
if ($db->connect_error) {
die("Connection failed this is the error: " . $db->connect_error);
}
$stmt = $db->prepare("INSERT INTO studentrecords (Name, email, Phone, school,dob,father,feereceived,due,image) VALUES (?,?,?,?,?,?,?,?,?)");
if($stmt)
{
$stmt->bind_param("ssisssiis",$name,$email,$phone,$school,$dob,$father,$feereceived,$due,$fileUploaded);
$stmt->execute();
$out="<center>information entered.</center>";
echo "$out";
}
else
{
$out="DATABASE ERROR!!!";
echo "$out";
}
return $out;
}
Here is the function save()
public function save(){
$folderIsWriteAble = is_writable( $this->destination );
if( $folderIsWriteAble ){
$name = "$this->destination/$this->filename";
if($succes = move_uploaded_file( $this->fileData, $name ))
{
return $name;
}
}
}
#Micky you have only 9 fields defined in your insert query but you are passing 10 parameters in ´bind_param()`.
$stmt->bind_param("ssisssiis",$name,$email,$phone,$school,$dob,$father,$feereceived,$due,$fileUploaded);
should be
$stmt->bind_param($name,$email,$phone,$school,$dob,$father,$feereceived,$due,$fileUploaded);
If it doesn’t resolve your problem then var_dump your $fileUploaded variable and make sure you have compatible datatype defined for column used for storing file name.
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.
public function deleteuser()
{
$this->sql = " SELECT admin_img FROM admin_data WHERE admin_id = '$this->admin_id' ";
$this->res = mysqli_query($this->conxn, $this->sql)
or trigger_error($this->err = mysqli_error($this->conxn));
$this->numRows = mysqli_num_rows($this->res);
$this->data = mysqli_fetch_assoc($this->res);
//filename
$file_name = $this->data['admin_img'];
$destination="Uploads/".$file_name;
//delete the file
if(file_exists($destination)){
if(unlink($destination)){
//file removed from the server
//now remove from the database
$this->sql = " DELETE FROM admin_data WHERE admin_id = '$this->admin_id' ";
$this->res = mysqli_query($this->conxn, $this->sql)
or trigger_error($this->err = mysqli_error($this->conxn));
$this->affRows = mysqli_affected_rows($this->conxn);
echo $this->affRows;
if($this->affRows>0){
return TRUE;
}
else{
return FALSE;
}
else{
return FALSE;
}
}//delete file ends
I have unlinked the file which i uploaded but i can remove the data which i stored while adding the user with file.
I am not getting any errors too but the code is always returning False
I want the code to return true value.
Please help me **
**Thanks in advance
try this in your unlink if condition
while unlinking you need to give your root path
if(file_exists($_SERVER['DOCUMENT_ROOT'].$destination)){
if(unlink($_SERVER['DOCUMENT_ROOT'].$destination)){
//your delete code
}
}
I am very new to php programming. I have written a sign up html file where the user enters his email and password. If the user has already registered, I am redirecting to sign-in screen and if the user is new use, I am persisting in the database. Now if the user enters wrong password, he will again be redirected to sign-in screen but this time I want to show a message on the screen, that the password entered is incorrect. The sign in screen should not display the message when the user navigates directly to the sign in screen.
The code snippet is shown below:
<?php
define('DB_HOST', 'hostname');
define('DB_NAME', 'db_name');
define('DB_USER','username');
define('DB_PASSWORD','password');
$con=mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die("Failed to connect to MySQL: " . mysql_error());
$db=mysql_select_db(DB_NAME,$con) or die("Failed to connect to MySQL: " . mysql_error());
function NewUser() {
$email = $_POST['email'];
$password = $_POST['password'];
$query = "INSERT INTO WebsiteUsers (email,pass) VALUES ('$email','$password')";
$data = mysql_query ($query)or die(mysql_error());
if($data) {
header('Location: reg-success.html');
}
}
function SignUp() {
if(!empty($_POST['email'])){
$emailQuery = mysql_query("SELECT * FROM WebsiteUsers WHERE email = '$_POST[email]'");
if($row = mysql_fetch_array($emailQuery)) {
$query = mysql_query("SELECT * FROM WebsiteUsers WHERE email = '$_POST[email]' AND pass = '$_POST[password]'");
if($row = mysql_fetch_array($query)) {
echo 'validated user. screen that is accessible to a registered user';
}else{
echo 'Redirect to the sign in screen with error message';
}
}else{
NewUser();
}
}
}
if(isset($_POST['submit']))
{
SignUp();
}
?>
Please let me know how to get this implementation using php
Here are a couple of classes that may help you prevent injection hacks plus get you going on how to do what you are trying to do in general. If you create classes for your tasks, it will be easier to re-use what your code elsewhere. I personally like the PDO method to connect and grab info from a DB (you will want to look up "binding" to help further prevent injection attacks), but this will help get the basics down. This is all very rough and you would want to expand out to create some error reporting and more usable features.
<?php
error_reporting(E_ALL);
// Create a simple DB engine
class DBEngine
{
protected $con;
// Create a default database element
public function __construct($host = '',$db = '',$user = '',$pass = '')
{
try {
$this->con = new PDO("mysql:host=$host;dbname=$db",$user,$pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
}
catch (Exception $e) {
return 0;
}
}
// Simple fetch and return method
public function Fetch($_sql)
{
$query = $this->con->prepare($_sql);
$query->execute();
if($query->rowCount() > 0) {
$rows = $query->fetchAll();
}
return (isset($rows) && $rows !== 0 && !empty($rows))? $rows: 0;
}
// Simple write to db method
public function Write($_sql)
{
$query = $this->con->prepare($_sql);
$query->execute();
}
}
// Your user controller class
class UserControl
{
public $_error;
protected $db;
// Save the database connection object for use in this class
public function __construct($db)
{
$this->_error = array();
$this->db = $db;
}
// Add user to DB
protected function Add()
{
$email = htmlentities($_POST['email'],ENT_QUOTES);
// Provided you have a php version that supports better encryption methods, use that
// but you should do at least a very basic password encryption.
$password = hash('sha512',$_POST['password']);
// Use our handy DBEngine writer method to write your sql
$this->db->Write("INSERT INTO WebsiteUsers (`email`,`pass`) VALUES ('$email','$password')");
}
// Fetch user from DB
protected function Fetch($_email = '')
{
$_email = htmlentities($_email,ENT_QUOTES);
$password = hash('sha512',$_POST['password']);
// Use our handy DBEngine fetcher method to check your db
$_user = $this->db->Fetch("SELECT * FROM WebsiteUsers WHERE email = '$_email' and password = '$password'");
// Return true if not 0
return ($_user !== 0)? 1:0;
}
// Simple fetch user or set user method
public function execute()
{
// Check that email is a valid format
if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
// Save the true/false to error reporting
$this->_error['user']['in_db'] = $this->Fetch($_POST['email']);
// Asign short variable
$_check = $this->_error['user']['in_db'];
if($_check !== 1) {
// Add user if not in system
$this->Add();
// You'll want to expand your add feature to include error reporting
// This is just returning that it made it to this point
$this->_error['user']['add_db'] = 1;
}
else {
// Run some sort of login script
}
// Good email address
$this->_error['email']['validate'] = 1;
}
else
// Bad email address
$this->_error['email']['validate'] = 0;
}
}
// $_POST['submit'] = true;
// $_POST['email'] = 'jenkybad<script>email';
// $_POST['password'] = 'mypassword';
if(isset($_POST['submit'])) {
// Set up a db connection
$db = new DBEngine('hostname','dbname','dbuser','dbpass');
// Create instance of your user control
$_user = new UserControl($db);
// Execute instance
$_user->execute();
// Check for basic erroring
print_r($_user->_error);
} ?>
For some reason the return doesn't work when the check_em() succeeds. I'm new to php, so I'm at a loss here.
<?php
//Class to handle mysql
class db_handler {
private $db_host = 'localhost';
private $db_name = 'project';
private $db_user = 'project';
private $db_pass = 'dbpassword';
private $db_con_mysql = '';
private $db_con_db = '';
public function check_em($username, $password) {
$db_query = "SELECT password FROM user WHERE name='".$username."' LIMIT 1;";
if($this->db_con_mysql!='') {
$db_query_response = mysql_query($db_query) or die('Query failed: '.mysql_error());
$db_query_return = mysql_fetch_row($db_query_response);
$db_sha1_hash = $db_query_return[0];
echo $db_sha1_hash."<br>";
echo sha1($password)."<br>";
if(sha1($password)==$db_sha1_hash) {
return 'user valid'; //THIS DOESN'T WORK!?!?!?
} else {
return 'no good';
}
} else {
$this->db_connect();
$this->check_em($username, $password);
}
}
//Connect to mysql, then database
private function db_connect() {
$this->db_con_mysql = mysql_connect($this->db_host, $this->db_user, $this->db_pass) || die('Connection failed: '.mysql_error());
$this->db_con_db = mysql_select_db($this->db_name) || die('Could not use'.$this->db_name.'. '.mysql_error());
return;
}
//Disconnect from database and reset vars used to track connection.
private function db_disconnect() {
if($this->db_con_mysql!='') {
mysql_close();
$this->db_con_mysql = '';
$this->db_con_db = '';
return;
}
}
public function fake($some_val) {
if($some_val<6) {
return TRUE;
} else {
return FALSE;
}
}
}
$db_obj = new db_handler();
$val1 = $db_obj->check_em('someuser','password'); //should return 'user valid'
echo "val1:".$val1."<br>";
echo "<br><br>";
$val2 = $db_obj->check_em('someuser','passw0rd'); //should return 'no good'
echo "val2:".$val2."<br>";
echo "<br><br>";
echo "test<br>";
echo $db_obj->fake(4)."<br>";
?>
Results:
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
val1:
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
7c6a61c68ef8b9b6b061b28c348bc1ed7921cb53
val2:no good
test
1
This line needs a return:
return $this->check_em($username, $password);
But a more sensible solution would be to connect to the database inside the if when the connection is null. Really, the whole thing could be better written, but I'll leave it at that.
...
else {
$this->db_connect();
return $this->check_em($username, $password);
}
...
You want to add the return, so that if it fails, then it goes one level deeper and finds another. If that level deeper succeeds, it passes the value up to the level above, which can pass it up and up until it reaches the original function call.