/    Sign up×
Community /Pin to ProfileBookmark

How to: Upload images using PHP

[i][If you have any questions or comments about this thread, please see [url=http://www.webdeveloper.com/forum/showthread.php?t=96532]this thread[/url]. – MOD][/i]

How to upload images using PHP is one of the most frequently asked questions in this PHP forum so I am going to use this post to look at the basics.

Uploading images can be broken down into the three following steps which will be looked at in turn:

[list]

  • [*]

    An HTML form with a browse button to allow the client to choose which file to upload


  • [*]

    A script to process the upload, validate the file, name it and place it in the file system


  • [*]

    Lastly a page to advise the client the upload was a success


  • [/list]

    Let’s start with the HTML form.

    [code=php]<?php

    // filename: upload.form.php

    // first let’s set some variables

    // make a note of the current working directory relative to root.
    $directory_self = str_replace(basename($_SERVER[‘PHP_SELF’]), ”, $_SERVER[‘PHP_SELF’]);

    // make a note of the location of the upload handler script
    $uploadHandler = ‘http://’ . $_SERVER[‘HTTP_HOST’] . $directory_self . ‘upload.processor.php’;

    // set a max file size for the html upload form
    $max_file_size = 30000; // size in bytes

    // now echo the html page
    ?><!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN”
    “http://www.w3.org/TR/html4/strict.dtd”>

    <html lang=”en”>
    <head>
    <meta http-equiv=”content-type” content=”text/html; charset=iso-8859-1″>

    <link rel=”stylesheet” type=”text/css” href=”stylesheet.css”>

    <title>Upload form</title>

    </head>

    <body>

    <form id=”Upload” action=”<?php echo $uploadHandler ?>” enctype=”multipart/form-data” method=”post”>

    <h1>
    Upload form
    </h1>

    <p>
    <input type=”hidden” name=”MAX_FILE_SIZE” value=”<?php echo $max_file_size ?>”>
    </p>

    <p>
    <label for=”file”>File to upload:</label>
    <input id=”file” type=”file” name=”file”>
    </p>

    <p>
    <label for=”submit”>Press to…</label>
    <input id=”submit” type=”submit” name=”submit” value=”Upload me!”>
    </p>

    </form>

    </body>

    </html>[/code]

    The form is just basic HTML but has one very important part which is often accidently omitted making file uploads impossible. This item is contained in the <form> tag, be sure to include it:

    [CODE]<form id=”Upload” action=”<?php echo $uploadHandler ?>” [color=red]enctype=”multipart/form-data”[/color] method=”post”>[/CODE]

    The other important thing of course is the file <input> tag.

    [CODE]<input id=”file” [color=red]type=”file”[/color] name=”file”>[/CODE]

    Lastly, while still on the subject of the upload form, it is possible to add an optional [I]hidden[/I] <input> tag which contains the maximum upload filesize and this should come before the file upload field. The value of this field is the filesize in bytes.

    Now on to the upload processing script. This script runs in a linear way and if any step of the script is not satisfied the script will abort and output an error message. The comments in the script explain what each step does, and doesn’t really require further explanation.

    [code=php]<?php

    // filename: upload.processor.php

    // first let’s set some variables

    // make a note of the current working directory, relative to root.
    $directory_self = str_replace(basename($_SERVER[‘PHP_SELF’]), ”, $_SERVER[‘PHP_SELF’]);

    // make a note of the directory that will recieve the uploaded file
    $uploadsDirectory = $_SERVER[‘DOCUMENT_ROOT’] . $directory_self . ‘uploaded_files/’;

    // make a note of the location of the upload form in case we need it
    $uploadForm = ‘http://’ . $_SERVER[‘HTTP_HOST’] . $directory_self . ‘upload.form.php’;

    // make a note of the location of the success page
    $uploadSuccess = ‘http://’ . $_SERVER[‘HTTP_HOST’] . $directory_self . ‘upload.success.php’;

    // fieldname used within the file <input> of the HTML form
    $fieldname = ‘file’;

    // Now let’s deal with the upload

    // possible PHP upload errors
    $errors = array(1 => ‘php.ini max file size exceeded’,
    2 => ‘html form max file size exceeded’,
    3 => ‘file upload was only partial’,
    4 => ‘no file was attached’);

    // check the upload form was actually submitted else print the form
    isset($_POST[‘submit’])
    or error(‘the upload form is neaded’, $uploadForm);

    // check for PHP’s built-in uploading errors
    ($_FILES[$fieldname][‘error’] == 0)
    or error($errors[$_FILES[$fieldname][‘error’]], $uploadForm);

    // check that the file we are working on really was the subject of an HTTP upload
    @is_uploaded_file($_FILES[$fieldname][‘tmp_name’])
    or error(‘not an HTTP upload’, $uploadForm);

    // validation… since this is an image upload script we should run a check
    // to make sure the uploaded file is in fact an image. Here is a simple check:
    // getimagesize() returns false if the file tested is not an image.
    @getimagesize($_FILES[$fieldname][‘tmp_name’])
    or error(‘only image uploads are allowed’, $uploadForm);

    // make a unique filename for the uploaded file and check it is not already
    // taken… if it is already taken keep trying until we find a vacant one
    // sample filename: 1140732936-filename.jpg
    $now = time();
    while(file_exists($uploadFilename = $uploadsDirectory.$now.’-‘.$_FILES[$fieldname][‘name’]))
    {
    $now++;
    }

    // now let’s move the file to its final location and allocate the new filename to it
    @move_uploaded_file($_FILES[$fieldname][‘tmp_name’], $uploadFilename)
    or error(‘receiving directory insuffiecient permission’, $uploadForm);

    // If you got this far, everything has worked and the file has been successfully saved.
    // We are now going to redirect the client to a success page.
    header(‘Location: ‘ . $uploadSuccess);

    // The following function is an error handler which is used
    // to output an HTML error page if the file upload fails
    function error($error, $location, $seconds = 5)
    {
    header(“Refresh: $seconds; URL=”$location””);
    echo ‘<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN”‘.”n”.
    ‘”http://www.w3.org/TR/html4/strict.dtd”>’.”nn”.
    ‘<html lang=”en”>’.”n”.
    ‘ <head>’.”n”.
    ‘ <meta http-equiv=”content-type” content=”text/html; charset=iso-8859-1″>’.”nn”.
    ‘ <link rel=”stylesheet” type=”text/css” href=”stylesheet.css”>’.”nn”.
    ‘ <title>Upload error</title>’.”nn”.
    ‘ </head>’.”nn”.
    ‘ <body>’.”nn”.
    ‘ <div id=”Upload”>’.”nn”.
    ‘ <h1>Upload failure</h1>’.”nn”.
    ‘ <p>An error has occured: ‘.”nn”.
    ‘ <span class=”red”>’ . $error . ‘…</span>’.”nn”.
    ‘ The upload form is reloading</p>’.”nn”.
    ‘ </div>’.”nn”.
    ‘</html>’;
    exit;
    } // end error handler

    ?>[/code]

    If the script above came to its conclusion without any error the client will be redirected to a success (A.K.A. [I]landing[/I]) page. The following is an example of such a page:

    [code=php]<?php

    // filename: upload.success.php

    ?><!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN”
    “http://www.w3.org/TR/html4/strict.dtd”>

    <html lang=”en”>
    <head>
    <meta http-equiv=”content-type” content=”text/html; charset=iso-8859-1″>

    <link rel=”stylesheet” type=”text/css” href=”stylesheet.css”>

    <title>Successful upload</title>

    </head>

    <body>

    <div id=”Upload”>
    <h1>File upload</h1>
    <p>Congratulations! Your file upload was successful</p>
    </div>

    </body>

    </html>[/code]

    Finally to tie everything together we need a simple stylesheet:

    [code=html]#Upload {
    width: 25em;
    margin: 1em auto;
    padding:0 2em 2em 2em ;
    border:1px solid #bbb;
    color: #333;
    background:#ffd;
    font: 0.9em verdana, sans-serif;
    }

    #Upload h1{
    font: 1.4em bold verdana, sans-serif;
    margin: 0;
    padding:1em 0;
    text-align:center;
    }
    #Upload label{
    float: left;
    width: 7em;
    }

    #Upload p {
    clear: both;
    }

    .red{
    color:red;
    }[/code]

    [B]Permissions:[/B] I’m not going to go into perrmissions in this article as it is a platform specific issue and also varies from server to server depending on the how the server has been configured. General speaking the files will be created 0644 but if that is not the case on your server you will need to [URL=http://www.php.net/chmod]chmod()[/URL] them to at least this permission for them to be web viewable. For more information on the configuration of your particular server consult your host’s FAQs.

    That’s about it. I have put the whole thing in a zip file which contains all the directories and files needed and which will work without modification if uploaded to a server.

    If you are still unclear about image uploads please consider studying the following offical documentation before posting a question in the forum:

    [list]

  • [*]

    [URL=http://www.php.net/features.file-upload]Handling file uploads[/URL]


  • [*]

    [URL=http:/www.php.net/manual/features.file-upload.errors.php]Error Messages Explained[/URL]


  • [*]

    [URL=http://www.php.net/is_uploaded_file]is_uploaded_file()[/URL]


  • [*]

    [URL=http://www.php.net/move_uploaded_file]move_uploaded_file()[/URL]


  • [*]

    [URL=http://www.php.net/getimagesize]getimagesize()[/URL]


  • [/list]

    [upl-file uuid=7a521c92-2db7-43e6-91db-0f41e35cdef5 size=3kB]uploader.zip[/upl-file]

    to post a comment
    PHP

    2 Comments(s)

    Copy linkTweet thisAlerts:
    @bokehauthorApr 02.2006 — Multiple uploads are pretty much the same as simple uploads but with few subtle differences. This post looks at these differences.

    First the upload form:[code=php]<?php

    // filename: upload.form.php

    // first let's set some variables

    // make a note of the current working directory relative to root.
    $directory_self = str_replace(basename($_SERVER['PHP_SELF']), '', $_SERVER['PHP_SELF']);

    // make a note of the location of the upload handler
    $uploadHandler = 'http://' . $_SERVER['HTTP_HOST'] . $directory_self . 'multiple.upload.processor.php';

    // set a max file size for the html upload form
    $max_file_size = 30000; // size in bytes

    // now echo the html page
    ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">

    <html lang="en">
    <head>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">

    <link rel="stylesheet" type="text/css" href="stylesheet.css">

    <title>Upload form</title>

    </head>

    <body>

    <form id="Upload" action="<?php echo $uploadHandler ?>" enctype="multipart/form-data" method="post">

    <h1>
    Upload form
    </h1>

    <p>
    <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max_file_size ?>">
    </p>

    <p>
    <label for="file1">File to upload:</label>
    <input id="file1" type="file" name="file[]">
    </p>

    <p>
    <label for="file2">File to upload:</label>
    <input id="file2" type="file" name="file[]">
    </p>

    <p>
    <label for="file3">File to upload:</label>
    <input id="file3" type="file" name="file[]">
    </p>

    <p>
    <label for="submit">Press to...</label>
    <input id="submit" type="submit" name="submit" value="Upload us!">
    </p>

    </form>


    </body>

    </html>[/code]
    The form is almost identical to the simple upload form except it has multiple file <input> fields. Each <input> file is as follows:[CODE]<input id="file1" type="file" name="[color=red]file[][/color]">[/CODE]Note the square brackets following the field name; this tells PHP that it is an array of files rather than just a single file.

    Now the uploads processing script.

    It is possible to do this several ways; either the whole script can be looped for each file or we could loop each step of the script for each file. I have opted for the second method as this means nothing will have already been saved in the case of an error.[code=php]<?php

    // filename: upload.processor.php

    // first let's set some variables

    // make a note of the current working directory, relative to root.
    $directory_self = str_replace(basename($_SERVER['PHP_SELF']), '', $_SERVER['PHP_SELF']);

    // make a note of the directory that will recieve the uploaded files
    $uploadsDirectory = $_SERVER['DOCUMENT_ROOT'] . $directory_self . 'uploaded_files/';

    // make a note of the location of the upload form in case we need it
    $uploadForm = 'http://' . $_SERVER['HTTP_HOST'] . $directory_self . 'multiple.upload.form.php';

    // make a note of the location of the success page
    $uploadSuccess = 'http://' . $_SERVER['HTTP_HOST'] . $directory_self . 'multiple.upload.success.php';

    // name of the fieldname used for the file in the HTML form
    $fieldname = 'file';

    //echo'<pre>';print_r($_FILES);exit;



    // Now let's deal with the uploaded files

    // possible PHP upload errors
    $errors = array(1 => 'php.ini max file size exceeded',
    2 => 'html form max file size exceeded',
    3 => 'file upload was only partial',
    4 => 'no file was attached');

    // check the upload form was actually submitted else print form
    isset($_POST['submit'])
    or error('the upload form is neaded', $uploadForm);

    // check if any files were uploaded and if
    // so store the active $_FILES array keys
    $active_keys = array();
    foreach($_FILES[$fieldname]['name'] as $key => $filename)
    {
    if(!empty($filename))
    {
    $active_keys[] = $key;
    }
    }

    // check at least one file was uploaded
    count($active_keys)
    or error('No files were uploaded', $uploadForm);

    // check for standard uploading errors
    foreach($active_keys as $key)
    {
    ($_FILES[$fieldname]['error'][$key] == 0)
    or error($_FILES[$fieldname]['tmp_name'][$key].': '.$errors[$_FILES[$fieldname]['error'][$key]], $uploadForm);
    }

    // check that the file we are working on really was an HTTP upload
    foreach($active_keys as $key)
    {
    @is_uploaded_file($_FILES[$fieldname]['tmp_name'][$key])
    or error($_FILES[$fieldname]['tmp_name'][$key].' not an HTTP upload', $uploadForm);
    }

    // validation... since this is an image upload script we
    // should run a check to make sure the upload is an image
    foreach($active_keys as $key)
    {
    @getimagesize($_FILES[$fieldname]['tmp_name'][$key])
    or error($_FILES[$fieldname]['tmp_name'][$key].' not an image', $uploadForm);
    }

    // make a unique filename for the uploaded file and check it is
    // not taken... if it is keep trying until we find a vacant one
    foreach($active_keys as $key)
    {
    $now = time();
    while(file_exists($uploadFilename[$key] = $uploadsDirectory.$now.'-'.$_FILES[$fieldname]['name'][$key]))
    {
    $now++;
    }
    }

    // now let's move the file to its final and allocate it with the new filename
    foreach($active_keys as $key)
    {
    @move_uploaded_file($_FILES[$fieldname]['tmp_name'][$key], $uploadFilename[$key])
    or error('receiving directory insuffiecient permission', $uploadForm);
    }

    // If you got this far, everything has worked and the file has been successfully saved.
    // We are now going to redirect the client to the success page.
    header('Location: ' . $uploadSuccess);

    // make an error handler which will be used if the upload fails
    function error($error, $location, $seconds = 5)
    {
    header("Refresh: $seconds; URL="$location"");
    echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"'."n".
    '"http://www.w3.org/TR/html4/strict.dtd">'."nn".
    '<html lang="en">'."n".
    ' <head>'."n".
    ' <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">'."nn".
    ' <link rel="stylesheet" type="text/css" href="stylesheet.css">'."nn".
    ' <title>Upload error</title>'."nn".
    ' </head>'."nn".
    ' <body>'."nn".
    ' <div id="Upload">'."nn".
    ' <h1>Upload failure</h1>'."nn".
    ' <p>An error has occured: '."nn".
    ' <span class="red">' . $error . '...</span>'."nn".
    ' The upload form is reloading</p>'."nn".
    ' </div>'."nn".
    '</html>';
    exit;
    } // end error handler

    ?>[/code]
    Pretty much everything else is the same as in a case of a simple upload.

    As before a zip file has been added. This is a full working version.

    [upl-file uuid=91b2729d-ff47-47bb-b590-7aca10f73dbc size=4kB]multiple_uploader.zip[/upl-file]
    Copy linkTweet thisAlerts:
    @LiLcRaZyFuZzYApr 02.2006 — great. mods, that should be a sticky
    ×

    Success!

    Help @bokeh spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 4.26,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @Yussuf4331,
    tipped: article
    amount: 1000 SATS,

    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,

    tipper: @Samric24,
    tipped: article
    amount: 1000 SATS,
    )...