LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 06-25-2012, 12:39 PM   #1
errigour
Member
 
Registered: May 2009
Posts: 278

Rep: Reputation: 5
Question about an unexpected T_VARIABLE


How come the code below gives me the error below?

Code snippet:
Code:
    $filename = $_FILES["file"]["name"]
    $ext = substr(strrchr($filename, '.'), 1);
Error message:
Code:
Parse error: syntax error, unexpected T_VARIABLE in ************** on line 43

Last edited by errigour; 06-25-2012 at 12:41 PM. Reason: To remove location of local directories
 
Old 06-25-2012, 12:48 PM   #2
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,590

Rep: Reputation: 412Reputation: 412Reputation: 412Reputation: 412Reputation: 412
Remove the dollar sign infront of the variable you are trying to declare. You do not add a dollar sign when you are declaring a variable, only when you are calling upon it.
 
Old 06-25-2012, 01:20 PM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 12,175

Rep: Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784
What is posted is the proper PHP syntax.
It might just be a typo but you are missing a ; on the first line posted.
 
Old 06-25-2012, 01:23 PM   #4
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,590

Rep: Reputation: 412Reputation: 412Reputation: 412Reputation: 412Reputation: 412
Didn't notice it was PHP first time through, just saw the dollar signs and assumed BASH. My first post is incorrect for PHP, thanks for catching it michaelk
 
Old 06-26-2012, 12:10 AM   #5
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
Ok I added a semicolon and it still gives me this error.

Code:
Notice: Undefined index: file in C:\Apache2.2\htdocs\Post Picture\Upload File.php on line 42 Home PageFile is not a recognized extension

line 42 is:
$filename = $_FILES["file"]["name"];
 
Old 06-26-2012, 05:52 AM   #6
michaelk
Moderator
 
Registered: Aug 2002
Posts: 12,175

Rep: Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784
Without seeing your code I can only guess.
Does your form match your PHP code i.e. something like
Quote:
Choose a file to upload: <input name="file" type="file" />
 
Old 06-26-2012, 06:53 AM   #7
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Quote:
Originally Posted by errigour View Post
Ok I added a semicolon and it still gives me this error.

Code:
Notice: Undefined index: file in C:\Apache2.2\htdocs\Post Picture\Upload File.php on line 42
That is not an error, it is just a notice. It means there was no "file" entry in the $_FILES array. That happens when you don't supply a file to be uploaded, or do a GET query to the script instead of a POST one. You can suppress the notice by using
Code:
$filename = @$_FILES["file"]["name"];
but then $filename === NULL if there was no uploaded file.

I hope I'm not offending you, but perhaps it would be worth your while to read some PHP tutorials first? Many are poor in quality -- I haven't found one I'd be comfortable with --, so I'm afraid you'll have to rely on a number of sources simultaneously. For example, I'd rather not have to explain here why there are three consecutive equals signs in the statement above: it is a very basic, core PHP operator you should be comfortable with.
 
Old 06-26-2012, 07:14 AM   #8
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
Well the reason I asked is because there wasn't a null file sent. That line doesn't work even if there is a file present using the post method. Ill post the code if you want but it only messes up when I substr that string.

---------- Post added 06-26-12 at 07:15 AM ----------

Code:
<?php
function foldersize($path) {

    $total_size = 0;
    $files = scandir($path);


    foreach($files as $t) {

        if (is_dir(rtrim($path, '/') . '/' . $t)) {

            if ($t<>"." && $t<>"..") {

                $size = foldersize(rtrim($path, '/') . '/' . $t);

                $total_size += $size;
            }
        } else {

            $size = filesize(rtrim($path, '/') . '/' . $t);

            $total_size += $size;
        }
    }

    return $total_size;
}

if($_FILES["file"]["error"] > 0)
{
    if($_FILES["file"]["error"] = 4)
    {
        echo "Non existing file recieved<br>";
        include('index.html');
        exit;
    }
    echo "Error: " . $_FILES["file"]["error"] . "<br>";
}
else
{
    $size = foldersize("Temporary Internet Files/");

    if ($size >= 500000)
    {
        echo "<a href=\"../\">Home Page</a>";
        echo "File size on disk has exceeded<BR>\n";
        exit;
    }
    if($_FILES["file"]["size"] > 570000)
    {
        echo "File size exceeds 5.4 Megabytes<br>";
        include('index.html');
        exit;
    }
    if(file_exists("Temporary Internet Files" . $_FILES["file"]["name"]))
    {
        echo $_FILES["file"]["name"] . " already exists. <BR>";
        include('index.html');
        exit;
    }
    else
    {
        move_uploaded_file($_FILES["file"]["tmp_name"], "Temporary Internet Files/" . $_FILES['file']['name']);
        echo "Upload   : " . ($_FILES["file"]["name"]) . "<br>\n";
        echo "Type     : " . ($_FILES["file"]["type"]) . "<br>\n";
        echo "Size     : " . ($_FILES["file"]["size"] / 1024) . " Kb<br>\n";
        echo "TMP File : " . $_FILES["file"]["tmp_name"] . "<br>\n";
        echo "Stored In: " . "Temporary Internet Files/" . $_FILES["file"]["name"] . "<BR>\n";
        echo "<BR><BR><BR><BR>\n";
        echo "<img src=\"Temporary Internet Files/" . $_FILES["file"]["name"] . "\"><BR>\n";
    }
}
?>
 
Old 06-26-2012, 08:50 AM   #9
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Quote:
Originally Posted by errigour View Post
Well the reason I asked is because there wasn't a null file sent.
Null file?

The PHP page can be reached in multiple ways.

POST upload only occurs if the page is reached due to a <form method="POST" action="URL-to-PHP-page" ... (or equivalent Javascript, or equivalent request in any programming language). A normal request, a GET request, occurs when the PHP page is reached via a simple link, for example when the user simply types out the URL to the PHP page.

For GET requests, both $_POST and $_FILES arrays will be empty or NULL. If the user does not pick a file to be uploaded, or the foo in <input type="file" name="foo" ... in the upload form does not match, then $_FILES["foo"] emits the exact notification you saw, and @$_FILES["foo"]["name"] === NULL.

I don't understand where you got the concept of a null file from, honestly.

According to the POST method uploads documentation at php.net, the name field in the entry in the $_FILES array is the original file name as reported by the browser. The file name used for the uploaded (temporary) file is in the tmp_name field.

The original file name must not be trusted. It is a very common attack vector, and very simple to do in practice, to supply a malicious file name and/or path, especially ones containing ../ or /../../../../../../../../ . Let that sink in for a moment, and look at what your code is doing. Yes, yes, we all know you'll add the security stuff later on, when you have free time; for now, you just want the code to work.

I'm just saying that that approach is doomed. You'd do better to do it right from the get go.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

I suspect that the primary problem is a disconnect between the HTML upload form and this PHP code. There may be a typo in the input field name, for example; or you might have forgotten the enctype="multipart/form-data" attribute from the form element.

To easily debug those, I personally use a simple PHP page that dumps out the contents of the various arrays. You can use something as simple as
PHP Code:
<?PHP
header
('Content-Type: text/plain; charset=UTF-8');

echo 
"GET:\n"var_dump(@$_GET);
echo 
"\nPOST:\n"var_dump(@$_POST);
echo 
"\nFILES:\n"var_dump(@$_FILES);
?>
although I personally prefer a nice nested HTML table. If you have that somewhere on your development server, you can temporarily change the action of the form element to point to that, and look at exactly what fields the browser sends. If there are any errors in the output, you need to fix the upload form.

If you use a single PHP file to both provide the upload form and to process it, you must understand that when the client browser asks for the form first, there will be no POST data, no FILES: it is a normal GET request.

When you save a file uploaded by a client, and you wish to use the original file name, you should apply some serious sanitization to the $_FILES["foo"]["name"] value before using it. The most robust approach I can think of is to first obtain a description of all uploaded files, something like
Code:
$uploads = 0;             /* Number of uploaded files */
$upload_temp = array();   /* Temporary filename */
$upload_size = array();   /* Uploaded file size in bytes */
$upload_html = array();   /* Field name in HTML code */
$upload_name = array();   /* Original filename, untrustworthy */
$upload_mime = array();   /* Upload mime type, untrustworthy */
$upload_errors = array(); /* Error codes and their counts */

foreach ($_FILES as $htmlname => $info)
    if (is_array(@$info["error"])) {
        foreach ($info["error"] as $key => $error)
            if ($error === 0) {
                $upload_temp[$uploads] = @$info["tmp_name"][$key];
                $upload_size[$uploads] = @$info["size"][$key];
                $upload_html[$uploads] = $htmlname;
                $upload_name[$uploads] = @$info["name"][$key];
                $upload_mime[$uploads] = @$info["type"][$key];
                $uploads++;
            } else
                $upload_errors[$error]++;
    } else
    if (@$info["error"] === 0) {
        $upload_temp[$uploads] = @$info["tmp_name"];
        $upload_size[$uploads] = @$info["size"];
        $upload_html[$uploads] = $htmlname;
        $upload_name[$uploads] = @$info["name"];
        $upload_mime[$uploads] = @$info["type"];
        $uploads++;
    } else
        $upload_errors[@$info["error"]]++;
which works even when multiple files are selected, and completely ignores the HTML names given to the file input entries. If you use Javascript or similar to use multiple copies of the same file input element in the HTML, remember to specify the name as an array, ie. in HTML, <input type="file" name="foo[]" ... .

If there are errors, it usually means the entire upload is shot. I for one would not trust any part of a failed upload.

Next, I'd clean up the $upload_name array. My preferred tool for that is preg_replace(), something like the following:
Code:
for ($u = 0; $u < $uploads; $u++) {
    $name = $upload_name[$u];

    /* Remove any leading directory components. */
    $name = preg_replace('/^.*[\\:\/]+/', "", $name);

    /* Keep only alphanumerics, dashes, underscores, full stops. */
    $name = preg_replace('/[^-.0-9A-Z_a-z]+/', "", $name);

    /* A full stop must be preceded and followed by a number or letter. */
    $name = preg_replace('/[^0-9A-Za-z]*\.[^0-9A-Za-z]*/', "", $name);

    /* Make sure the name starts and stops with a number or letter. */
    $name = preg_replace('/^[^0-9A-Za-z]+/', "", $name);
    $name = preg_replace('/[0-9A-Za-z]+$/', "", $name);

    /* Note: $name may be empty, if it was bad enough. */

    $upload_name[$u] = $name;
}
I've never used the $upload_mime array, as the contents are usually completely bogus. For example, people using Windows, have a lot of JPEG files named with a .gif suffix, and therefore boldly claimed to be image/gif by the browser. Incorrectly.

In fact, I only use the tmp_name, size, and after heavy filtering as above, name.

I assure you, this all works if you have your Apache correctly configured, proper PHP settings allowing file uploads, and a working PHP script. If you cannot get yours to work, one of those is incorrect.
 
Old 06-26-2012, 02:20 PM   #10
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
Yea It works fine without the two lines I posted. Maybe you could help me, I want to check to make sure the file name is an image file otherwise people will wonder why they could post strange files and see nothing but a missing image box on the page.

Here's the form in action
http://o0oo0.net16.net/Post Picture/

Try and post a file that's not an image.

Here's the html form:
Code:
<form action="Upload File.php" method="post" enctype="multipart/form-data">

        <h1>
            Post A Picture
        </h1>

        <p>
            <label>File to upload:</label>
            <input id="file" type="file" name="file">
            <input id="submit" type="submit" name="submit" value="Submit">
        </p>
</form>
 
Old 06-26-2012, 09:52 PM   #11
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Quote:
Originally Posted by errigour View Post
I want to check to make sure the file name is an image file otherwise people will wonder why they could post strange files and see nothing but a missing image box on the page.
I personally do that using getimagesize(). Although it is a GD function, it does not require the GD library; meaning it should work even when GD itself is not available.

Code:
$info = @getimagesize(@$_FILES["file"]["tmp_name"]);
$name = FALSE;
$error = array();

if (is_array($info) && count($info) >= 3) {

    /* Check uploaded image type. */
    switch ($info[2]) {
    case IMAGETYPE_GIF:  $name = ".gif"; break;
    case IMAGETYPE_PNG:  $name = ".png"; break;
    case IMAGETYPE_JPEG: $name = ".jpg"; break;
    default:             $name = FALSE;
                         $error[] = "Uploaded file is not a GIF, JPEG, or PNG image.";
    }

    /* Only allow 100 .. 3200 pixels wide images. */
    if ($info[0] < 100) {
        $name = FALSE;
        $error[] = "Image is not wide enough.";
    }
    if ($info[0] > 3200) {
        $name = FALSE;
        $error[] = "Image is too wide.";
    }

    /* Only allow 100 .. 3200 pixels tall images. */
    if ($info[1] < 100) {
        $name = FALSE;
        $error[] = "Image is not tall enough.";
    }
    if ($info[1] > 3200) {
        $name = FALSE;
        $error[] = "Image is too tall.";
    }
}

/* Use the original file name, if it is an image. */
if ($name !== FALSE) {
    $temp = @$_FILES["file"]["name"];
    $temp = preg_replace('/^.*\/+/', "", $temp);
    $temp = preg_replace('/\.[^.]*$/', "", $temp);
    $temp = preg_replace('/[^-0-9A-Z_a-z]+/', "", $temp);
    $temp = preg_replace('/^[^0-9A-Za-z]+/', "", $temp);
    $temp = preg_replace('/[^0-9A-Za-z]+$/', "", $temp);
    if (strlen($name) > 0)
        $name = $temp . $name;
    else {
        $name = FALSE;
        $error[] = "Original image file name cannot be used; please rename file first.";
    }
}

/*
 * At this point:
 *    if ($name !== FALSE) {
 *        the uploaded file is an image, and $name is a suitable
 *        permanent file name for it.
 *    } else
 *    if (count($error) < 1) {
 *        there was no uploaded file.
 *    } else {
 *        the entries in the $error array tell the user why
 *        the uploaded file is unacceptable. For example:
 *        foreach ($error as $msg) echo $msg, "<br>\n";
 *    }
*/
 
Old 06-27-2012, 06:57 AM   #12
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
For some reason it doesn't seem to work for me.

---------- Post added 06-27-12 at 06:58 AM ----------

Code:
    $info = getimagesize(@$_FILES["file"]["tmp_name"]);
    $name = FALSE;
    $error = array();

    if (is_array($info) && count($info) >= 3)
    {

        /* Check uploaded image type. */
        switch ($info[2])
        {
            case IMAGETYPE_GIF:  $name = ".gif"; break;
            case IMAGETYPE_PNG:  $name = ".png"; break;
            case IMAGETYPE_JPEG: $name = ".jpg"; break;
            case IMAGETYPE_JPEG: $name = ".jpeg"; break;
            default:             $name = FALSE;
        }
    }

    if( $name = FALSE )
    {
        echo "Uploaded file is not a GIF, JPEG, or PNG image.<BR>\n";
        include('index.html');
        exit;
    }

Last edited by errigour; 06-27-2012 at 06:58 AM.
 
Old 06-27-2012, 08:18 AM   #13
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Quote:
Originally Posted by errigour View Post
For some reason it doesn't seem to work for me.
That's weird. 000webhost.com does have GD installed for PHP. What happens, exactly?

To debug partial failures (like POST data being intact but uploaded file missing), add
Code:
echo "<!-- Files:\n";
var_dump(@$_FILES); 
echo "\n-->";
in your PHP page somewhere, so you can see the exact contents of the $_FILES array by looking at the page source.
 
Old 06-27-2012, 09:49 AM   #14
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
I'm testing it on my home page I didn't try with web host, also why do you add the two echo lines to that code?
 
Old 06-27-2012, 11:12 AM   #15
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Quote:
Originally Posted by errigour View Post
why do you add the two echo lines to that code?
So that the dump is in a HTML comment.

Here is a tested, working, but very bare-bones upload script:
Code:
<?PHP

    header('Content-Type: text/html; charset=utf-8');

    define('UPLOADS_DIR', 'path-to-upload-directory');
    define('UPLOADS_URL', 'url-to-upload-directory');

?><html>
 <head>
  <title> Upload test </title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 </head>
 <body>

<?PHP

    $uploads = 0;
    $upload_name = array(); /* Original names */
    $upload_temp = array(); /* Temporary names */
    $upload_size = array(); /* Size in bytes */
    $upload_info = array(); /* Information */

    foreach (@$_FILES as $set)
        if (is_array($set["error"])) {
            foreach ($set["error"] as $key => $error)
                if ($error === 0) {
                    $uploads++;
                    $upload_name[$uploads] = $set["name"];
                    $upload_temp[$uploads] = $set["tmp_name"];
                    $upload_size[$uploads] = $set["size"];
                    $upload_info[$uploads] = array();
                }
        } else
        if ($set["error"] === 0) {
            $uploads++;
            $upload_name[$uploads] = $set["name"];
            $upload_temp[$uploads] = $set["tmp_name"];
            $upload_size[$uploads] = $set["size"];
            $upload_info[$uploads] = array();
        }

    for ($u = 1; $u <= $uploads; $u++) {
        $name = $upload_name[$u];
        $upload_name[$u] = FALSE;

        if (($info = @getimagesize($upload_temp[$u])) !== FALSE) {
            switch ($info[2]) {
            case IMAGETYPE_GIF:  $ext = ".gif"; $desc = "GIF image"; break;
            case IMAGETYPE_PNG:  $ext = ".png"; $desc = "PNG image"; break;
            case IMAGETYPE_JPEG: $ext = ".jpg"; $desc = "JPEG image";break;
            default:             $ext = FALSE;
            }
            if ($ext === FALSE)
                continue;

            if ($info[0] < 16 || $info[0] > 4096 ||
                $info[1] < 16 || $info[1] > 4096)
                continue;

            $temp = $name;

            $temp = preg_replace('/^.*\/+/', "", $temp);
            $temp = preg_replace('/\.[^\.]*$/', "", $temp);
            $temp = preg_replace('/[^-0-9A-Z_a-z]+/', "", $temp);
            $temp = preg_replace('/^[^0-9A-Za-z]+/', "", $temp);
            $temp = preg_replace('/[^0-9A-Za-z]+$/', "", $temp);
            if (strlen($temp) < 1)
                continue;

            $upload_info[$u]["original"] = $name;
            $upload_info[$u]["filesize"] = $upload_size[$u];
            $upload_info[$u]["width"] = $info[0];
            $upload_info[$u]["height"] = $info[1];
            $upload_info[$u]["type"] = $info[2];
            $upload_info[$u]["desc"] = $desc;

            /* Note: should check against overwriting existing files here!
            */

            if (@move_uploaded_file($upload_temp[$u], UPLOADS_DIR . "/" . $temp . $ext) !== FALSE)
                $upload_name[$u] = $temp . $ext;
        }
    }

    for ($u = 1; $u <= $uploads; $u++)
        if ($upload_name[$u] !== FALSE) {
            $url = UPLOADS_URL . "/" . htmlentities($upload_name[$u], ENT_QUOTES, "utf-8");
            echo '<p><a href="', $url, '"><img src="', $url,
                 '" width="', $upload_info[$u]["width"],
                 '" height="', $upload_info[$u]["height"],
                 '" alt="',
                 '" title="', htmlentities($upload_info[$u]["original"], ENT_QUOTES, "utf-8"),
                 ' - ', $upload_info[$u]["width"], "x", $upload_info[$u]["height"],
                 ' ', $upload_info[$u]["desc"], '" border="0">', 
                 "</a></p>\n";
        }

?>

  <form action="upload.php" method="post" enctype="multipart/form-data" accept-charset="utf-8">
   <fieldset>
    <legend> Image Upload </legend>
    <input type="file" name="image">
    <input type="submit" value="Upload">
   </fieldset>
  </form>

 </body>
</html>
This script both provides the upload form, and handles the upload itself, when saved as upload.php. For brevity, I dropped the error messages; it does check everything except it blithely overwrites already existing files in the upload directory.

It only accepts GIF, PNG, and JPEG images between 16x16 and 4096x4096 pixels; all other uploaded files are discarded. The original name, image type, and dimensions are shown in the image tooltip.
 
  


Reply

Tags
php


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Parse error: syntax error, unexpected T_VARIABLE in line 8 gsness Programming 8 01-31-2012 08:53 PM
unexpected restart - Uday123 Linux - Software 3 09-21-2009 09:25 PM
unexpected inconsistency anjala Linux - Server 1 11-27-2008 12:05 AM
unexpected T_VARIABLE in php script verbatim Programming 1 05-09-2005 01:21 PM
Unexpected Problem with XP Mandrake92 General 9 05-28-2004 11:52 AM


All times are GMT -5. The time now is 12:43 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration