Good Day Daniweb,

I am encountering a problem in php code meant to allow the user to update their profile picture.
I am using jquery.min and jquery.js. The code below runs with no errors reported. The file has been successfully uploaded to upload path using this form.

upload.php

<form  id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'>
<input type="file" name="photoimg" id="photoimg" class="stylesmall"/>
</form>

ajaximage.php

$path = "uploads/";
$valid_formats = array("jpg", "png", "gif", "bmp","jpeg");
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST")
{
$name = $_FILES['photoimg']['name'];
$size = $_FILES['photoimg']['size'];
if(strlen($name))
{
list($txt, $ext) = explode(".", $name);
if(in_array($ext,$valid_formats))
{
if($size<(1024*1024)) // Image size max 1 MB
{
$actual_image_name = $name.".".$ext;
$tmp = $_FILES['photoimg']['tmp_name'];
if(move_uploaded_file($tmp, $path.$actual_image_name))
{
$query   = "UPDATE users SET profile_image='$actual_image_name' WHERE student_id='{$_SESSION['user_id']}'";
$result = mysqli_query($link_id, $query);
echo "<img src='uploads/".$actual_image_name."' class='preview'>";
}

The problem is the image being uploaded does not display on the

Student_home.php

<div id="about-img">
    <img class="profile-photo" align="middle" src='uploads/".$actual_image_name."' />
</div>

But the image uploaded will display when i write directly its filename example

<div id="about-img">
    <img class="profile-photo" align="middle" src="uploads/107.jpg" />
</div>

My problem is i wanted to display the uploaded picture of the specific student on Student_Home.php

What does $actual_image_name equal?

Check view source on your page to see what it actually spits out into HMTL, as this is probably where our problem is hiding.

Member Avatar for diafol

there are quite a few issues with this script. never use explode to get the extension. pathinfo is designed for this. you seriously want to allow bmp files? WHy calculate 1024^2 seems wasteful?

$_POST is always set, but not always empty.
What happens when an user uploads an indentically named file?

Anyway - student_home.php - where is $actual_image_name set in the page before you use it in the src of the image tag? I hope you're not expecting the ajax script to carry this over for you.

@diafol:

Thanks for the advice, i already disallowed the bmp files.
$valid_formats = array("jpg", "png", "gif","jpeg");
I also change the $actual_image name to its session/student_id.
$actual_image_name = $session_id.".".$ext;

The uploaded image is currently renamed to the student id but still the image wont display on student_home.php :-(

Anyway - student_home.php - where is $actual_image_name set in the page before you use it in the src of the image tag? I hope you're not expecting the ajax script to carry this over for you.

I dont really have an idea how to do this one. I tried though by adding these codes in the student_home.php

<?php
$query = "SELECT users.profile_image FROM users AS users WHERE student_id='{$_SESSION['user_id']}'";
$result = mysqli_query($link_id, $query);
$actual_image_name = $result['profile_image'];
?>
<div id="about-img">
    <img class="profile-photo" align="middle" src='uploads/".$actual_image_name."' />
</div>

but still exasperately, the page wont display.

Member Avatar for diafol

It's a bit dangerous to use the session id in this context. The user's session is not fixed between sessions. Sometimes a session id may be regenerated too within the session itself depending on your code - so one to avoid.

You can store the image like this by all means, BUT what happens if an user uploads a second file in the same session?

Many of us rewrite files using a hash of microtime(). The chances of getting duplicate stored filenames is then pretty remote - well depending on the hashing method. Alternatively use something simple like the username and the time to build a name, e.g. diafol_20140916094513 and then tag on the extension.

You may find splitting your long procedural code into functions may help:

function process_file( $formUploadFieldName )
{
    //...
    return false or an array with $_FILES details 
}

function make_filename( )
{
    //without extension
   return $_SESSION['id'] . '_' . time();     
}

Etc. Making pieces of long code is terribly difficult, even for seasoned programmers. So by cutting it into functions (or even class methods for OOPers), then you can debug your code much easier. Just some friendly advice. :-)

I am only a beginner in PHP and i dont know much about calling functions specially the whole code of what you are suggesting. I had use renaming of files uploaded using time() but it fails to display the image the reason may be the time of upload is differ from the time of display (well it was not about using functions maybe your codes differs and possibly could display the image on student.home.php) As much as i need to build the whole codes, how well i know, don't have any idea to complete your codes hope i could borrow some of your knowledge even just this time hope it would not violate Daniweb and your principle.

Member Avatar for diafol

Our general philosophy is (well mine at least) is to help you get there yourself. So we can provide outlines and you colour in the spaces.

I'm on my break at the mo, but I'll have a think tonight and come back with more advice if somebody else doesn't do so first.

Just a quick thought have you checked what is stored in the database for the filename?

Member Avatar for diafol

Here's an example of how I might implement it...

session_start();
$inputFieldName = 'uploadfile';
$destination = "uploads";
$pdo = new PDO("mysql:host=localhost;dbname=daniweb","root","");
$prep = "INSERT INTO `userfiles` ( `user_id`, `upload_date`, `filename` ) VALUES ( :user_id, :upload_date, :filename )";

I'm assuming that your user will be logged in and will have his/her user_id stored in $_SESSION['user_id'].

if($_FILES)
{
    try{
        if($_FILES[$inputFieldName]['error'] === 0)
        {
            if( $name = copyTo( $destination )
            {
                $bind = array( ":user_id"=>$_SESSION['user_id'], "upload_date"=>date( 'Y-m-d H:i:s' ), "filename"=>$name );         

                if( addToDB( $pdo, $prep, $bind ) )
                {
                    //SUCCESS
                    echo "OK all done! <img src='$destination/$name' />";    
                }else{
                    echo "Couldn't add to DB";  
                }
            }
        }else{
            echo "Error = " . $_FILES[$inputFieldName]['Error'];    
        }
    } catch (Exception $e) {
        echo 'Caught exception: ',  $e->getMessage(), "\n";
    }
}

The above makes use of a couple of user-defined functions which if general enough can be reused if you have other upload routines.

function copyTo( $destination )
create a unique name for the file
attach the extension if it's allowed
copy the newly named file to the destination folder via move_uploaded_file()
return the name if all good or false if problem.

function addToDB( $pdo, $prep, $bind )
Bind the data, execute the statement and return the rowcount.

This is just an over-simplified way of doing it, but I hope it illustrates a way to cut up a long bit of procedural code. Sorry, that was a bit rushed and given a choice, I'd make an upload class.

commented: Nice one. +4

@noelthefish: the filename of the uploaded picture of the database is the $student_id itself

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.