?
Solved

PHP file upload and Delphi app

Posted on 2005-03-16
16
Medium Priority
?
3,720 Views
Last Modified: 2013-12-03
Hi,

( I know similiar questions have been asked many times)
  I found a php scipt to  upload file  to the web server
I uploaded script  into cgi-bin directory of the server and tried it by using IE,
when i entered http://www.mydomain.com/cgi-bin/upload.php
browser showed me Browse button, and UploadFile button, by using the browse button I selected the file to be uploaded and clicked on the UploadFile after that the file uploaded successfully, all worked OK.  

But I want to make the file uploading automatically by using a Delphi app, to do this ;
1- I used HttpCliExample (an application to upload file over HTTP, uses fpiette HttpCli component, and a perl script on the server side) it did not worked, (although program gave the message that it sent xxx bytes successfully)
2- After this failure, I used another program namely SocketSpy to capture the data sent by the IE (while uploading my file), I created a new application and used HttpCli component and sent the data that is same with the captured, again there was no file uploaded.

Could anyone send me a working example, my php script is the following;

<?php
$this_script = "upload.php";
$home_page = "home.htm";
$uploaddir = "./";
$type = array(".jpg",".gif",".txt");  // enter in all lower case
$maxSize = 100000;
$maxDisplay = $maxSize / 1000;
$maxFileSpace = 50000000;
?>
<html><head></head><body>
<div style="text-align: center; left: 30%; top: 50px; position: absolute; border: 1px black solid; width:400px; height:300px;">
<?php
// print_r($_FILES);  // can be used for debugging
$file_name = $_FILES['file']['name'];
$file_size = $_FILES['file']['size'];
$file_tmp_name = $_FILES['file']['tmp_name'];
if ($file_name) {
  $error = "";
  echo "<br>File Name: $file_name<br><br>";
  echo "File Size: $file_size<br><br>";
  // file size test
  if ($file_size == 0 ) $error .= "<font color=red>Invalid file</font><br>";
  if ($file_size > $maxSize ) $error .= "<font color=red>Your file exceeds $maxDisplay K.</font><br>";
  // file type test
  $type_test = strtolower(strstr($file_name, '.'));
  if (!in_array($type_test, $type) ) $error .= "<font color=red>Your file is not a valid file type.</font><br>";
  // max directory size test
  if ($dir = @opendir("$uploaddir")) {
    while (($file_select = readdir($dir)) !== false) {
      $type_test = strtolower(strstr($file_select, '.'));
      if (in_array($type_test,$type)) {
        $file_size_accum = filesize("$uploaddir$file_select");
        $total_size = $total_size + $file_size_accum;
      }
    }  
    closedir($dir);
  }
  if (($total_size+$file_size) >= $maxFileSpace)  $error .= "<font color=red>Total file space limits have been exceeded.</font><br>";
  // eliminate bad characters from the file name
  $file_name = stripslashes($file_name);
  $file_name = preg_replace("#[ ]#","_",$file_name);  // change spaces to underscore
  $file_name = preg_replace('#[^()\.\-,\w]#','_',$file_name);  //only parenthesis, underscore, letters, numbers, comma, hyphen, period - others to underscore
  $file_name = preg_replace('#(_)+#','_',$file_name);  //eliminate duplicate underscore
  // check for file already exists
  if (file_exists("$uploaddir$file_name")) $error .= "<font color=red>File already exists.</font><br>";
  // if all is valid, do the upload
  if ($error == "") {
    if (move_uploaded_file($file_tmp_name, "$uploaddir$file_name")) {
      chmod("$uploaddir$file_name", 0644);
      echo "<font color=green>Your file was successfully uploaded!</font>";
    } else {
      echo "<font color=red>Your file could not be uploaded.</font>";
    }
  }
  echo "$error<hr>";
} else {
  echo "<br><br><br><br>";
}

?>
Upload a <font color='blue'>
<?php
foreach($type as $print_type) { echo $print_type; }
?>
</font> file to our server<br>
Maximum file size is <?=$maxDisplay?> K
<form action="<?=$this_script?>" method="post" enctype="multipart/form-data">
File: <input type=file name="file" size=30><br>
<input type=submit name="submit" value="Upload File"></form>
<a href="<?=$home_page?>">Return to the Home Page</a>
</div></body></html>

I have been trying for 3 days but could not manage.

- Another question without using any component how can I use wininet in my app?

Thanks
0
Comment
Question by:new_x
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
16 Comments
 
LVL 46

Expert Comment

by:aikimark
ID: 13555294
Is your Delphi app a CGI program, desktop application, or runs in another environment?

If a desktop app, then add the FTP indy component to your project and use it to transfer the file.
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 13555880
0
 
LVL 26

Accepted Solution

by:
EddieShipman earned 2000 total points
ID: 13556262
Using the demo, I was able to make this work. I made some mods to the PHP to get it to work correctly
from being called by the Delphi app:

PHP:

<?php
$this_script = "upload.php";
$home_page = "index.html";
$uploaddir = "./";
$type = array(".jpg",".gif",".txt");  // enter in all lower case
$maxSize = 100000;
$maxDisplay = $maxSize / 1000;
$maxFileSpace = 50000000;
?>
<html><head></head><body>
<div style="text-align: center; left: 30%; top: 50px; position: absolute; border: 1px black solid; width:400px; height:300px;">
<?php
  if(count($_FILES)>0) {
  //print_r($_FILES);  // uncomment these two lines for debugging
  //exit();
  $file_name = $_FILES['file']['name'];
  $file_size = $_FILES['file']['size'];
  $file_tmp_name = $_FILES['file']['tmp_name'];
  if (isset($file_name)) {
    $error = "";
    echo "<br>File Name: $file_name<br><br>";
    echo "File Size: $file_size<br><br>";
    // file size test
    if ($file_size == 0 ) $error .= "<font color=red>Invalid file</font><br>";
    if ($file_size > $maxSize ) $error .= "<font color=red>Your file exceeds $maxDisplay K.</font><br>";
    // file type test
    $type_test = strtolower(strstr($file_name, '.'));
    if (!in_array($type_test, $type) ) $error .= "<font color=red>Your file is not a valid file type.</font><br>";
    // max directory size test
    if ($dir = @opendir("$uploaddir")) {
      while (($file_select = readdir($dir)) !== false) {
        $type_test = strtolower(strstr($file_select, '.'));
        if (in_array($type_test,$type)) {
          $file_size_accum = filesize("$uploaddir$file_select");
          $total_size = $total_size + $file_size_accum;
        }
      }  
      closedir($dir);
    }
    if (($total_size+$file_size) >= $maxFileSpace)  $error .= "<font color=red>Total file space limits have been exceeded.</font><br>";
    // eliminate bad characters from the file name
    $file_name = stripslashes($file_name);
    $file_name = preg_replace("#[ ]#","_",$file_name);  // change spaces to underscore
    $file_name = preg_replace('#[^()\.\-,\w]#','_',$file_name);  //only parenthesis, underscore, letters, numbers, comma, hyphen, period - others to underscore
    $file_name = preg_replace('#(_)+#','_',$file_name);  //eliminate duplicate underscore
    // check for file already exists
    if (file_exists("$uploaddir$file_name")) $error .= "<font color=red>File already exists.</font><br>";
    // if all is valid, do the upload
    if ($error == "") {
      if (move_uploaded_file($file_tmp_name, "$uploaddir$file_name")) {
        chmod("$uploaddir$file_name", 0644);
        echo "<font color=green>Your file was successfully uploaded!</font>";
      } else {
        echo "<font color=red>Your file could not be uploaded.</font>";
      }
    }
    echo "$error<hr>";
  } else {
    echo "<br><br><br><br>";
  }
} else {

echo "Upload a <font color='blue'>";
foreach($type as $print_type) { echo $print_type; }
echo "</font> file to our server<br>";
echo "Maximum file size is ".$maxDisplay." K";
echo "<form action=\"".$this_script."\" method=\"post\" enctype=\"multipart/form-data\">";
echo "File: <input type=\"file\" name=\"userfile\" size=\"30\"><br>";
echo "<input type=\"submit\" name=\"Submit\" value=\"Upload File\"></form>";
echo "<a href=\"".$home_page."\">Return to the Home Page</a>";

} ?>
</div></body></html>

Delphi: {just change this in the demo unit}
procedure TForm1.Button2Click(Sender: TObject);
var
  ResponseStream: TMemoryStream;
  MultiPartFormDataStream: TMsMultiPartFormDataStream;
begin
  MultiPartFormDataStream := TMsMultiPartFormDataStream.Create;
  ResponseStream := TMemoryStream.Create;
  try
    IdHttp1.Request.ContentType := MultiPartFormDataStream.RequestContentType;
    MultiPartFormDataStream.AddFile('file', edtFile.Text, edtMIMEType.Text);
    { You must make sure you call this method *before* sending the stream }
    MultiPartFormDataStream.PrepareStreamForDispatch;
    MultiPartFormDataStream.Position := 0;
    IdHTTP1.Post(edtHost.Text, MultiPartFormDataStream, ResponseStream);
  finally
    MultiPartFormDataStream.Free;
    ResponseStream.Position := 0;
    Memo1.Lines.LoadFromStream(ResponseStream);
    ResponseStream.Free;
  end;
end;

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:new_x
ID: 13561856
Hi aikimark
The Delphi application will be running at the client side and the php is running on the server side. Using ftp is not a choice, since I have to use http, I found the PHP script and uploaded it onto server.

EddieShipman, I will try your code, although I am not sure whether Indy suite comes with Delphi or not (I am using D7),

Thanks for your comments
0
 
LVL 1

Author Comment

by:new_x
ID: 13562437
Hi EddieShipman, thanks for your great help,  

I installed Indy Suite and compiled your code, changed and upload your modified php all thing went OK and worked.

when upload ended TIDTCPConnection.pas raised an exception  with a message
"EIdConnClosedGracefully with message 'Connection Closed Gracefully.'"

and in fact in this pas there is a brief explanation for this exception and for further explanation it suggests the user read help file. That is OK.

if I use your code, since Indy uses blocking socket calls, I have to create a thread for not having a frozen window...
May I post additional question since I have not used Indy before and may face another problem while testing your code with some other files.?

One final question if I want to use wininet library instead of component how could I implement your source? Since In fact  I have to implement this code based on the wininet library.




Thanks for your great help :-)
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 13565287
Use the TidAntiFreeze control to avoid the frozen Window, check the docs.

I only have the Indy tutorial, I will search for a file upload wininet tut. I don't think I've ever seen one.
0
 
LVL 1

Author Comment

by:new_x
ID: 13572289
I have also searching for wininet file uploading but could not have found yet, is there anything you found?
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 13574866
I just searched Tamaracka.om and found this. I haven't tested it so I don't know if it will work for you.

const
  BUFFERSIZE = 4096;

function TForm1.HttpPutFile(const ServerName, ObjectName,
  FileName: String): Boolean;
const
  ptNil: Pointer = nil;
var
  hOpenHandle, hConnectHandle, hResourceHandle: HINTERNET;
  lpdword: DWORD;
  dwTimeOut: DWORD;
  buf: array[0..BUFFERSIZE-1] of char;
  bufsize: DWORD;
  lf: file;
  err: Integer;
  fsize, tck: DWORD;
  TotSize: DWORD;
  bufferin: INTERNET_BUFFERS;
begin
  Result:=False;
  if FileExists(FileName) and
    HTTPGetFile(ServerName, '/install/id.txt', 'id.txt') then // <<<<< FORCE AUTHENTICATION !!!
  begin
    hOpenHandle:=InternetOpen('whatever', INTERNET_OPEN_TYPE_PRECONFIG,
      nil, nil, 0);
    if hOpenHandle<>nil then
    begin
      hConnectHandle:=InternetConnect(hOpenHandle, PChar(ServerName),
        INTERNET_INVALID_PORT_NUMBER, nil, nil,
        INTERNET_SERVICE_HTTP,0,0);
      if hConnectHandle<>nil then
      begin
        hResourceHandle:=HttpOpenRequest(hConnectHandle, 'POST',
          PChar(ObjectName), nil, nil, nil, INTERNET_FLAG_KEEP_CONNECTION or
          INTERNET_FLAG_NO_CACHE_WRITE, 0);
// dwTimeOut := 420000; // time out is set to 7 minutes // <<<<<<<<
USEFUL ???
// InternetSetOption(hResourceHandle,
INTERNET_OPTION_CONNECT_TIMEOUT, @dwTimeOut, 4);
// InternetSetOption(hResourceHandle,
INTERNET_OPTION_RECEIVE_TIMEOUT, @dwTimeOut, 4);
// InternetSetOption(hResourceHandle, INTERNET_OPTION_SEND_TIMEOUT,
@dwTimeOut, 4);
        if hResourceHandle<>nil then
        begin
          AssignFile(lf, FileName);
          FileMode:=0; // open as read-only
          Reset(lf,1);
          TotSize := FileSize(lf);

          err:=0;
          bufsize := BUFFERSIZE;
          fsize := 0;
          FillChar(bufferin, SizeOf(bufferin), 0);
          bufferin.dwStructSize := SizeOf(INTERNET_BUFFERS);
          bufferin.dwBufferTotal := TotSize;

          if HttpSendRequestEx(hResourceHandle, @bufferin, nil, HSR_INITIATE, 0) then
          begin
            tck := GetTickCount;

            while (bufsize = BUFFERSIZE) do
            begin
              BlockRead(lf, buf, BUFFERSIZE, bufsize);
              if not InternetWriteFile(hResourceHandle, @buf, bufsize, lpdword) then
              begin
                err:=GetLastError;
               Break;
              end;
              fsize := fsize + bufsize;
            end;
            if (err=0) and not HttpEndRequest(hResourceHandle, nil, 0, 0) then
            begin
              err:=GetLastError;
            end;
            Result := (err=0) and (fsize = TotSize);
          end
          else
          begin
            err:=GetLastError;
          end;
          CloseFile(lf);
          InternetCloseHandle(hResourceHandle);
        end;
        InternetCloseHandle(hConnectHandle);
      end;
      InternetCloseHandle(hOpenHandle);
    end;
  end;
end;
0
 
LVL 1

Author Comment

by:new_x
ID: 13582865
Hi EddieShipman, I called the function as below;

HttpPutFile('http://www.mydomain.com/cgi-bin/upload.php', 'test.jpg', 'c:\test.jpg');

but this HttpSendRequestEx call returned False


>>   if HttpSendRequestEx(hResourceHandle, @bufferin, nil, HSR_INITIATE, 0) then<<


          begin
            tck := GetTickCount;

            while (bufsize = BUFFERSIZE) do
            begin
              BlockRead(lf, buf, BUFFERSIZE, bufsize);
              if not InternetWriteFile(hResourceHandle, @buf, bufsize, lpdword) then
              begin
                err:=GetLastError;
               Break;
              end;
              fsize := fsize + bufsize;
            end;
            if (err=0) and not HttpEndRequest(hResourceHandle, nil, 0, 0) then
            begin
              err:=GetLastError;
            end;
            Result := (err=0) and (fsize = TotSize);
          end
          else
          begin
            err:=GetLastError;
          end;


I looked at the err value  which holds the lasterror, it was zero.

Regards,


0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 13591486
As I said, it was untested. Unfortunately, I do not have time to work on it today.
0
 
LVL 1

Author Comment

by:new_x
ID: 13598757
May be later,
 Regards
0
 
LVL 1

Author Comment

by:new_x
ID: 13649531
I want t&#305; thank to both of you..
Eddie thanks for your kind help :-)
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 13652357
Did you get it working?
0
 
LVL 1

Author Comment

by:new_x
ID: 13671343
No I did not get it working?.


0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 13671991
What problems are you having?
0
 
LVL 1

Author Comment

by:new_x
ID: 13688967
Hi Eddie,
I tried the code a few days ago and did not write down the exact problem
Let me just to try it again tomorrow.

Thanks for your interest


0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses
Course of the Month14 days, 7 hours left to enroll

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question