473,554 Members | 2,925 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

OOP clarification

348 Contributor
Hey everyone. I'm back in search of a better understanding of OOP. I feel like these past couple of months have paid off for me because I am at a point where I am really beginning to understand how this all works. I'd like to get some clarification on a few things first.

My questions stem from wanting to use private members and methods. I know that there is a reason for making methods and members public and private and honestly I'm still not totally clear as to when to use one over the other. I have been refactoring some of old classes and in looking at them, I was mortified. I figured that when I was redoing them that I should try and stick with private members and methods where possible because that's a good thing I guess.

I had download an app a while back that used 5 classes. Each class was like 1500 lines or so and the code looked clean to me. I figured that was a good way to program. I started to do the same thing but after looking over some of my classes, I quickly noticed that my classes were nothing more than functions instead of objects.

In refactoring this code, I separated out the methods that required functionality inside the class and set my constructor to call a main method that would do what was needed and then return out the values I needed. I just want to make certain that I understand correctly before I continue any further.

If I have a class like so:

Expand|Select|Wrap|Line Numbers
  1. class Hello{
  2.     public  $out;
  3.     private $text;
  4.  
  5.     public function __construct($text)
  6.     {
  7.         $this->text = $text;
  8.         $this->sayHello();
  9.     }
  10.  
  11.     private function sayHello()
  12.     {
  13.         $text = $this->text;
  14.         $var = 'Hello, my name is: ' . $text;
  15.         return $this->out = $var;
  16.     }
  17. }
  18.  
  19. $hello = new Hello('Tom');
  20. echo $hello->out;
To me, this seems like the correct way to write a class. I am returning out the values that I want. The way I was doing it in the past was to call the method directly and didn’t seem right.

Does this look correct? I have a few more questions but I'll wait on those for now to see what the feedback is on this. I'll also show you how I was doing before.

Thank!

Frank
May 19 '09
51 3494
dlite922
1,584 Recognized Expert Top Contributor
Frank,

To summarize, Classes should sort of "group" certain behavior or functionality together. For formatting an output (ie your hello example) a function would do, but let's say you had a formatter class that contained several of these things and were used through out your application. To this point, one of the core values of OOP is code reuse.

Also use OOP to define "objects" instead of "functions" . For example your application might have a User class, and ATM class, and a Storage class instead of having function classed like "Deposits", or "Transactio n" classes. These functions will fall into behaviors of the objects themselves, ie

User::setBalanc e("5000");
User::changeAdd ress("123 Main");
ATM::getMenuOpt ions();
Storage::record Transaction();

To me, it looks like you're on the right track. As you continue to read and write code, you'll be able to see what the best way to implement classes keeping the values of OOP in mind: Encapsulation, Code Reuse, Divide and concur the problem, and Bug Containment.

Next topic I recommend for you is Exceptions/Error handling.

BTW: I'd like to point out this has been the best OOP thread on bytes and see how others could benefit from it.

See you around!




Dan
May 21 '09 #11
Markus
6,050 Recognized Expert Expert
@Atli
Very well said. Great read :)
May 21 '09 #12
fjm
348 Contributor
There is some really great information here. Thanks for all the help guys. I am going to digest this and respond this weekend when I have a little more free time. I've already read this over once and will re-read it again this weekend before I respond. I'm not going to let this thread die!! :)
May 22 '09 #13
Markus
6,050 Recognized Expert Expert
@fjm
Go to your local library and find some books on programming design patterns / OOP. It doesn't really matter what language they're in; the concepts are relatively the same.
May 22 '09 #14
fjm
348 Contributor
Thanks for the advice Markus. I'll do that. I seem to do better with books anyhow.
May 25 '09 #15
fjm
348 Contributor
Ok, I spent the night writing a simple upload script that pretty much demonstrates what I am talking about. My first example sucked but the following is a class that can actually be used. The main goal of the class is to take a file from a user, clean the filename and upload it to the server. There are also options that the user can toggle in an array that's passed to the constructor.

When I designed this class, I didn't see any other public method that was needed, other than a simple message that lets the user know that something is wrong. It's because of this that I have made all of the members private as well as the methods.

Please have a look at it and let's discuss how it can be made better. I would also like to know if this is a decent class design.


Thanks,
Frank

Expand|Select|Wrap|Line Numbers
  1. <?php
  2. class FileUpload
  3. {
  4.     private $_upload = array();
  5.     private $_config = array();
  6.     private $_fileName;
  7.     private $_fileMime;
  8.     private $_fileSize;
  9.     private $_fileTemp;
  10.     private $_fileError;
  11.     private $_setFormName   = 'userfile';
  12.     private $_setExtension;
  13.     private $_setNewName;
  14.     private $_setUploadPath = null;
  15.     private $_setMaxSize    = 0;
  16.     public  $message;
  17.  
  18.     public function __construct( array $upload, array $config )
  19.     {
  20.         $this->_upload = $upload;
  21.         $this->_config = $config;
  22.         $this->setOptions();
  23.         $this->initialize();
  24.     }
  25.  
  26.     private function setOptions()
  27.     {
  28.         $opts = $this->_config;
  29.         foreach($opts as $opt => $val)
  30.         {
  31.             if(!empty($val))
  32.             {
  33.                 $this->{$opt} = $val;
  34.             }
  35.         }
  36.     }
  37.  
  38.     private function initialize()
  39.     {
  40.         $upload = $this->_upload;
  41.         $form   = $this->_setFormName;
  42.         if(!empty($upload["$form"]['name']))
  43.         {
  44.             if($this->testUploadDir())
  45.             {
  46.                 $this->_fileName  = $this->_upload["$form"]['name'];
  47.                 $this->_fileMime  = $this->_upload["$form"]['type'];
  48.                 $this->_fileSize  = $this->_upload["$form"]['size'];
  49.                 $this->_fileTemp  = $this->_upload["$form"]['tmp_name'];
  50.                 $this->_fileError = $this->_upload["$form"]['error'];
  51.                 $this->checkExtension();
  52.             }
  53.         }
  54.         else
  55.         {
  56.             $this->message = 'Please Select A File To Upload...';
  57.         }
  58.     }
  59.  
  60.     private function testUploadDir()
  61.     {
  62.         $path = $this->_setUploadPath;
  63.         if(file_exists($path))
  64.         {
  65.             if(!is_readable($path))
  66.             {
  67.                 $this->message = 'Upload Directory Not Readable';
  68.                 return false;
  69.             }
  70.             if(!is_writeable($path))
  71.             {
  72.                 $this->message = 'Upload Directory Not Writeable';
  73.                 return false;
  74.             }
  75.         }
  76.         else
  77.         {
  78.             $this->message = 'Upload Directory Does Not Exist';
  79.             return false;
  80.         }
  81.         return true;
  82.     }
  83.  
  84.     private function cleanFile()
  85.     {
  86.         $temp = $this->_fileName;
  87.         $temp = strtolower($temp);
  88.         $temp = str_replace(' ', '_', $temp);
  89.         $result = '';
  90.         for ($i=0; $i<strlen($temp); $i++)
  91.         {
  92.             if (preg_match("([0-9]|[a-z]|_|.)", $temp[$i]))
  93.             {
  94.                 $result = $result . $temp[$i];
  95.             }
  96.         }
  97.         $this->_fileName = $result;
  98.     }
  99.  
  100.     private function checkExtension()
  101.     {
  102.         $this->cleanFile();
  103.         $file   = $this->_fileName;
  104.         $getExt = substr($file, strpos($file,'.'), strlen($file)-1);
  105.         $setExt = $this->_setExtension;
  106.         if($getExt != $setExt)
  107.         {
  108.             $this->message = 'The File You Attempted To Upload Is Not Allowed.';
  109.             return false;
  110.         }
  111.         $this->checkSize();
  112.     }
  113.  
  114.     private function checkSize()
  115.     {
  116.         $size = $this->_fileSize;
  117.         $max  = $this->_setMaxSize;
  118.         if($max != 0)
  119.         {
  120.             if($size > $max)
  121.             {
  122.                 $this->message = 'The File You Attempted To Upload Is Too Large.';
  123.                 return false;
  124.             }
  125.         }
  126.         $this->renameFile();
  127.     }
  128.  
  129.     private function renameFile()
  130.     {
  131.         $old = $this->_fileName;
  132.         $new = $this->_setNewName;
  133.         if(!empty($new))
  134.         {
  135.             $this->_fileName = $new;
  136.         }
  137.         $this->moveFile();
  138.     }
  139.  
  140.     private function moveFile()
  141.     {
  142.         $temp      = $this->_fileTemp;
  143.         $file      = $this->_fileName;
  144.         $path      = $this->_setUploadPath;
  145.         $error     = $this->_fileError;
  146.         if($error == 0)
  147.         {
  148.             if(move_uploaded_file($temp,$path.$file))
  149.             {
  150.                 $this->message = 'Your File Upload Was Successful.';
  151.             }
  152.             else
  153.             {
  154.                 $this->message = 'Your File Upload Failed While Moving It To Its Permanent Location.';
  155.             }
  156.         }
  157.         else
  158.         {
  159.             $this->message = 'Your File Upload Failed. Errno: '.$error;
  160.         }
  161.     }
  162. }
  163.  
  164. $file = $_FILES;
  165. $config = array('_setFormName'=>'test','_setExtension'=>'.jpg','_setNewName'=>'new.jpg','_setUploadPath'  => './upload/','_setMaxSize'=>'0');
  166. $test = new FileUpload($file,$config);
  167. echo $test->message;
  168. ?>
  169. <form method="post" action="upload.php" enctype="multipart/form-data">
  170.   <input type="file" name="test" size="25">
  171.   <input type="submit" name="submit" value="Upload">
  172. </form>
May 25 '09 #16
Atli
5,058 Recognized Expert Expert
Ok. A few comments on that.

First: Having all the members private and passing their values via an array into the constructor.

The first thing that worries me about that is the fact that for this to work, the outside code must be aware of how the private internals of the class work (the private member names).
Because of this, you can not alter the internals of the class without having to change how the class is used by the outside.
You should be able to change every privately declared member or method without any change to how the class is used from the outside.

It's best to identify the values that must be provided and require them as parameters for the constructor.
Then identify additional values that can be provided and either add them to the constructor parameter list as optional parameters (parameters with default values) or add setters for them.

Ideally all the required values should have getters, and setters if possible, and the optional values should have both getters and setters.
That way the outside can at least read the values the class is using, and when possible, change them if that is needed.

You can of course add global setter method that takes a list of values to be set, but it is not a good idea to tie the keys used by the list to the actual names of the private members. Better to use aliases that are linked to the members, so the members themselves can be changed without affecting the outside.

Second: Chaining the private methods, starting at the constructor.

What I mean by this is; having one method trigger another when it is done, leading to the end.

The trouble with this is that the members are doing more then their names would suggest. For example, your "renameFile " method triggers the "moveFile" method when it is done, which is confusing at best.

You are basically doing something like this:
Expand|Select|Wrap|Line Numbers
  1. class example {
  2.   function trigger() {
  3.     // Some code...
  4.     task1();
  5.   }
  6.   function task1() {
  7.     // Some code...
  8.     task2();
  9.   }
  10.   function task2() {
  11.     task3();
  12.   }
  13.   function task3() {
  14.     // Some code...
  15.   }
  16.   // etc...
  17. }
If you plan to have one function trigger several others, like your code does, it would be better to execute them one by one from that function. Like:
Expand|Select|Wrap|Line Numbers
  1. class example {
  2.   function trigger() {
  3.     task1();
  4.     task2();
  5.     task3();
  6.   }
  7.   function task1() {
  8.     // Some code...
  9.   }
  10.   function task2() {
  11.     // Some code...
  12.   }
  13.   function taks3() {
  14.     // Some code...
  15.   }
  16.   // etc...
  17. }
This way each of the functions in the chain is only responsible for a single task; the one it's name indicates, which makes it re-usable and not tied to the trigger chain.

This also allows you better control over how they are executed. Exceptions and error codes could be used to alter the chain once it has started.

Third: Having all the functionality of the class executed by the constructor.

Even tho I see why you would want this, it's generally not a good idea to have a class act as a function. It limits the class, requiring all future use of it to at least include the functionality the constructor is tied to.

What if you choose to add FTP support to your FileUpload class later on?
You can't do that in any decent way, without changing the class in such a way that would break every previous use of it.

The constructor should be used to initialize the object, and then public methods should be used to execute whichever functionality of that class you intend to use.

This allows you to add to the class later without having to rewrite the outside code.


And lastly, I would avoid relying on a public member to relay the class methods error messages. It's better to have the methods themselves return boolean success values or error numbers.
Or better yet; have them throw exceptions.

It just makes for much cleaner code.

That doesn't mean you can't have your class provide past error messages via a public member or a getter. I would just not force users of the class to use them.
May 26 '09 #17
fjm
348 Contributor
Hold on.... I think I understand what you are saying here Atli.. So you mean.. it isn't good to tie all of my "functional ity" to the constructor because I limit the class. Yes? Here's what I think I am understanding.. By not tying al of my functionality to the constructor and by using getters and setters, I just use those for any current functionality I have or need and then if I require more functionality, I just add more getters and setters. With these getter and setter methods, I don't limit the outside code. Am I right?

Would it be possible to have you, in your spare time of course, maybe rework this class the way that you think it should be? Because I made that, I would be able to easily follow along on your changes and may be able to ask you more direct questions. The animal class was cool and I gained a lot of insight from it, but it isn't real world stuff. In fact, I looked it over and thought I was doing the same thing whan I made the upload class.

[quote=Atli;3490 078]You should be able to change every privately declared member or method without any change to how the class is used from the outside.

Ok, is this what you mean by change privately declared member:

Expand|Select|Wrap|Line Numbers
  1. class Color
  2. {
  3.     private $_color;
  4.  
  5.     public function __construct()
  6.     {
  7.     }
  8.  
  9.     function getColor()
  10.     {
  11.       return $this->_color;
  12.     }
  13.  
  14.     function setColor($color)
  15.     {
  16.       $this->_color = $color;
  17.     }
  18. }
  19. $foo = new Color();
  20. $foo->setColor('red');
  21. echo $foo->getColor(); // outputs red
  22.  
  23. $foo->setColor('blue);
  24. echo $foo->getColor(); //outputs blue
  25.  
Notice that I didn't make the get and set methods private because they would throw an error when I tried to access them so I left them public but that isn't right, is it?


@Atli
Could you elaborate on this a bit? What is a parameter list? Are these the values passed into the constructor?

@Atli
Can you provide a short example of this?

@Atli
I kind of felt that was incorrect. I actually made like a trigger method as you had done in your example but was having a problem getting the methods to work correctly. method C was dependant on B and B was dependant on A. When I just listed them like you showed, All of the methods would execute. In order for me to get them to work like that, I had to nest them based on their return values. Was this right?

@Atli
When you say "initialize the object" what exactly does that mean? What if there are no params required for the constructor? Do you mean that I should initialze all my class members in the constructor?

@Atli
Of course, if I did it this way, I'd have to make these methods public, right?

@Atli
I've been using exceptions now for a couple of weeks. I'm still not 100% certain how an exception is really any different than a if/else statement. I'm sure there is a huge difference but I can't see it yet.

Thanks again Atli for all the help!

Frank
May 26 '09 #18
Dormilich
8,658 Recognized Expert Moderator Expert
@fjm
When an exception is thrown, code following the statement will not be executed, and PHP will attempt to find the first matching catch block.
that means, the Exception will descend through the function/method stack not executing any code until it is caught.

taking Atli's 2nd example, if an Exception is thrown in task1(), task2() and task3() are not executed and if the Exception is not caught at all a catchable fatal error is thrown.
May 26 '09 #19
Atli
5,058 Recognized Expert Expert
Ok, this is a bit different from your class, but should at help explain what I'm talking about.

This is how I would have written a class like the one you posted.
(Been meaning to make a proper uploader class for ages anyways :P)

It is made so that you can move multiple files with one instance, so I removed most of the private members you used and added getter and setters for the once I left and added.

I also inlined most of the private methods into a public 'moveFile' method and a private 'validateFile' method, which do all the work.
The constructor just initializes the members and makes sure everything is ready.

I'm not sure how much you've used exceptions, but I use them in this class for error handling. Hope that doesn't get in your way.

I may have "over-commented" it a bit, but I always do that :P
(See an example of how to use it at the bottom)
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. /**
  3.  * Handles file uploads from a HTTP POST request.
  4.  * @throws Exception
  5.  */
  6. class FileUpload
  7. {
  8.     /** Property values **/
  9.     protected $_uploadDir; // Where to save the files
  10.     protected $_maxFileSize; // In bytes
  11.     protected $_allowedTypes; // A list of allowed mime types and their file extensions.
  12.  
  13.     /**
  14.      * The constructor. All parameters are optional.
  15.      * @param [string] $uploadDir The directory where files should be moved.
  16.      * @param [integer] $maxFileSize The maximum size of a uploaded file in bytes.
  17.      * @throws Exception
  18.      */
  19.     public function __construct($uploadDir="", $maxFileSize=2097152)
  20.     {
  21.         // Verify that there were some files uploaded
  22.         if(!$_FILES || count($_FILES) <= 0) {
  23.             throw new Exception("No files were uploaded.");
  24.         }
  25.  
  26.         // Initialize the properties
  27.         $this->setUploadDir($uploadDir);
  28.         $this->_maxFileSize = $maxFileSize;
  29.         $this->_allowedTypes = array(
  30.             'image/jpeg' => array('jpeg', 'jpg'),
  31.             'image/jpg'  => array('jpeg', 'jpg'),
  32.             'image/png'  => array('png'),
  33.             'image/gif'  => array('gif')
  34.         );
  35.     }
  36.  
  37.     /**
  38.      * Moves a file from it's temporary upload location to the upload dir.
  39.      * @param string $elemName The name given to the <input> element of the form
  40.      * @param [string] $newName A new name for the file, excluding the extension.
  41.      * @throws Exception
  42.      */
  43.     public function moveFile($elemName, $newName=null)
  44.     {
  45.         try {
  46.             // Make sure the file is valid
  47.             $this->validateFile($elemName);
  48.  
  49.             // Parse the file name and extension
  50.             $baseName = basename($_FILES[$elemName]['name']);
  51.             $fileName = substr($baseName, 0, strripos($baseName, "."));
  52.             $fileExt = substr($baseName, strripos($baseName, ".") + 1);
  53.  
  54.             // Set and clean the name
  55.             if($newName != null) {
  56.                 $fileName = $newName;
  57.             }
  58.             $fileName = $this->cleanFileName($fileName);
  59.  
  60.             // Move the file
  61.             $newPath = $this->_uploadDir . $fileName . $fileExt;
  62.             if(!move_uploaded_file($_FILES[$elemName]['tmp_name'], $newPath)) {
  63.                 throw new Exception("Could not save file '{$newPath}'");
  64.             }
  65.             return true;
  66.         }
  67.         catch(Exception $ex) {
  68.             throw new Exception("File relocation failed: " . $ex->getMessage());
  69.         }
  70.     }
  71.  
  72.     /**
  73.      * Converts a filename into a 'clean' format.
  74.      * @param string $fileName The filename to clean
  75.      * @return string The result of the cleaning
  76.      */
  77.     private function cleanFileName($fileName)
  78.     {
  79.         $temp = $fileName;
  80.         $temp = strtolower($temp);
  81.         $temp = str_replace(' ', '_', $temp);
  82.         $result = '';
  83.         for ($i=0; $i<strlen($temp); $i++)
  84.         {
  85.             if (preg_match("([0-9]|[a-z]|_|.)", $temp[$i]))
  86.             {
  87.                 $result = $result . $temp[$i];
  88.             }
  89.         }
  90.         return $result;
  91.     }
  92.  
  93.     /**
  94.      * Makes sure a uploaded file is valid and ready to be moved.
  95.      * @param string $elemName The name given to the <input> element of the form
  96.      * @return bool
  97.      * @throws Exception
  98.      */
  99.     private function validateFile($elemName)
  100.     {
  101.         // Make sure the element exists
  102.         if(!isset($_FILES[$elemName])) {
  103.             throw new Exception("No upload named '{$elemName}' was found");
  104.         }
  105.  
  106.         // Make sure the file was uploaded without a error
  107.         if($_FILES[$elemName]['error'] != 0) {
  108.             throw new Exception("File upload failed with code #". $_FILES[$elemName]['error']);
  109.         }
  110.  
  111.         // Make sure the file extension and mime type are valid
  112.         $fileExt = substr($_FILES[$elemName]['name'], strripos($_FILES[$elemName]['name'], ".") + 1);
  113.         $fileMime = $_FILES[$elemName]['type'];
  114.  
  115.         if(!in_array($fileMime, array_keys($this->_allowedTypes)) ||
  116.             !in_array($fileExt, $this->_allowedTypes[$fileMime]))
  117.         {
  118.             throw new Exception("File mime or extension is not valid.");
  119.         }
  120.  
  121.         // Make sure the file size is correct and within limits
  122.         if($_FILES[$elemName]['size'] != filesize($_FILES[$elemName]['tmp_name'])) {
  123.             throw new Exception("Uploaded size and actual size do not match");
  124.         }
  125.         if($_FILES[$elemName]['size'] > $this->_maxFileSize) {
  126.             throw new Exception("File size is to big");
  127.         }
  128.         return true;
  129.     }
  130.  
  131.     /** UploadDir and MaxFileSize properties (getters and setters) **/
  132.     public function setUploadDir($newPath) {
  133.         // Format the path
  134.         $newPath = str_replace('\\\\', "/", $newPath);
  135.         if($newPath[strlen($newPath)-1] != "/") {
  136.             $newPath .= "/";
  137.         }
  138.  
  139.         // Make sure the path is accessible
  140.         if(file_exists($newPath) && is_writeable($newPath)) {
  141.             $this->_uploadDir = $newPath;
  142.         }
  143.         else {
  144.             throw new Exception('Upload directory is inaccessible.');
  145.         }
  146.     }
  147.     public function getUploadDir() {
  148.         return $this->_uploadDir;
  149.     }
  150.     public function setMaxFileSize($newValue) {
  151.         if(is_integer($newValue) && $newValue > 0) {
  152.             $this->_maxFileSize = $newValue;
  153.         }
  154.         else {
  155.             throw new Exception("The max file size must be a positive integer.");
  156.         }
  157.     }
  158.     public function getMaxFileSize() {
  159.         return $this->_maxFileSize;
  160.     }
  161.  
  162.     /** Getters and setters to add / retrive allowed mime types and extensions */
  163.     public function addAllowedMimeType($mime, $extensions) {
  164.         foreach($extensions as $_ext) {
  165.             $_ext = strtolower($_ext);
  166.             if(!array_key_exists($mime, $this->_allowedTypes) ||
  167.                !array_search($_ext, $this->_allowedTypes[$mime]))
  168.             {
  169.                 $this->_allowedTypes[$mime][] = $_ext;
  170.             }
  171.         }
  172.     }
  173.     public function getAllowedMimeTypes() {
  174.         return array_keys($this->_allowedTypes);
  175.     }
  176.     public function getAllowedMimeExtensions($mimeType) {
  177.         if(array_key_exists($mimeType, $this->_allowedTypes)) {
  178.             return $this->_allowedTypes[$mimeType];
  179.         }
  180.     }
  181.     public function getAllowedExtensions() {
  182.         $outputArray = array();
  183.         foreach($this->_allowedTypes as $_type) {
  184.             $diff = array_diff($_type, $outputArray);
  185.             $outputArray = array_merge($outputArray, $diff);
  186.         }
  187.         return $outputArray;
  188.     }
  189. }
Which could be used like so:
Expand|Select|Wrap|Line Numbers
  1. <form method="post" action="?" enctype="multipart/form-data">
  2.     <input type="file" name="imageFile" /><br />
  3.     <input type="file" name="mp3File" /><br />
  4.     <input type="submit" name="submit" value="Upload" />
  5. </form>
  6. <?php
  7. if(isset($_POST['submit'])) {
  8.     require("FileUpload.php");
  9.     try {
  10.         // Create a FileUploader, specifying the upload path in the constructor
  11.         $uploader = new FileUpload("images");
  12.  
  13.         // Move the image file using the default settings
  14.         $uploader->moveFile("imageFile");
  15.         echo "<h3>First file uploaded</h3>";
  16.  
  17.         // Change the the upload path and max file size.
  18.         $uploader->setUploadDir("music/");
  19.         $uploader->setMaxFileSize(10485760); // 10MB
  20.  
  21.         // Allow the Mp3 mime and extension and move the Mp3 file.
  22.         $uploader->addAllowedMimeType("audio/mpeg", array("mp3"));
  23.         $uploader->moveFile("mp3File");
  24.         echo "<h3>Second file uploaded</h3>";
  25.  
  26.         // List all allowed mime types and their extensions
  27.         echo "<pre>";
  28.         foreach($uploader->getAllowedMimeTypes() as $_mime) {
  29.             echo "<strong>{$_mime}</strong> (";
  30.             $extensions = $uploader->getAllowedMimeExtensions($_mime);
  31.             echo implode(", ", $extensions), ")\n";
  32.         }
  33.         echo "</pre>";
  34.  
  35.     }
  36.     catch(Exception $ex) {
  37.         // Show error message
  38.         echo "<div><h3><span style='color: red;'>Exception cought!</font></h3>
  39.               <pre>", $ex->getMessage(), "</pre></div>";
  40.     }
  41. }
  42. ?>
May 26 '09 #20

Sign in to post your reply or Sign up for a free account.

Similar topics

3
2199
by: Wes | last post by:
I am trying to secure different files, mostly pdf, so only the person suppose to see the file that was designed for that individual can see it. I am using sessions to secure the actual web pages, but now I am trying to secure non-php files. Here is where I need some help/clarification. I was told to save the files outside the Web...
4
2875
by: Shea Martin | last post by:
Which of the following do I use delete instead of just delete. //1.) // not sure about this one, as char is of size 1 char *str = new char; //2.) //not sure about this one, as it is a primitive int *array = new int;
3
4069
by: John D. Sanders | last post by:
I have just upgraded MySQL from version 3.23 to version 4.1.8 and now I am getting the following error when I try to run a script that worked: install_driver(mysql) failed: Can't load '/usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi/auto/DBD/mysql/mysql.so' for module DBD::mysql: libmysqlclient.so.10: cannot open shared object...
2
4544
by: Ethan | last post by:
This is a clarification of a previous message, which was not expressed very well. I have a set of checkboxes near the bottom of the page and a function that checks or unchecks all of them. But when the function runs, the window scrolls to the top of the page. How can I set my checkboxes but leave the window's scroll position exactly where...
9
2581
by: Adam | last post by:
Hi, I am having problems having an include file rendered in my browser (IE6). The include file contains <A href> tags to be used as a navigation bar in the footer of a .html file. I am using dreamweaver and the included html appears as expected in the 'Design View' but does not get rendered in the browser.
3
1405
by: ma740988 | last post by:
Consider the 'C' source. void myDoorBellISR(starLinkDevice *slDevice, U32 doorBellVal) { doorBellDetected = doorBellVal; } void slRcv() { starLinkOpenStruct myOpenStruct;
3
2406
by: solomon_13000 | last post by:
> Wonthaggi Civic Theatre 'WCT' Case Study > > The town of Wonthaggi has a theatre which is owned and > operated by the local council, it is called the > Wonthaggi Civic Theatre (WCT) and a wide variety of > shows are presented there, for example plays, music > and talks. The management has decided to build a > computer system for WCT to...
0
288
by: chanchito_cojones | last post by:
Hi there, I was searching the net for some guidance in putting together a query that would select random records from the main table. I came across this and it works like a charm. SELECT TOP 5 * FROM tablename ORDER BY Rnd(IsNull(fieldname)*0+1);
8
1820
by: Sai Kit Tong | last post by:
In the article, the description for "Modiy DLL That Contains Consumers That Use Managed Code and DLL Exports or Managed Entry Points" suggests the creation of the class ManagedWrapper. If I need to build multiple mixed mode dll's used by a consumer application, do I have to implement multiple ManagedWrapper's (each embedded in indiviudal...
2
2908
by: ravir | last post by:
Hi, I am new to this group. I am working in Perl and shellscripts. I have a clarification regarding perl grep and pattern matching. I am writing a perl script to automate the process of code review upto some level so that the reviewer and developer's time can be reduced during the code review. In my script, I am using pattern matching and...
0
7496
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7778
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8008
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
6114
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5135
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3538
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3525
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1109
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
810
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.