This was actually an assignment given to me as part of an interview process some time back. The brief was simple: to have an upload utility that allowed a search term to be specified and a text file to be uploaded, with the contents of the uploaded file then displayed in the browser with the search term highlighted.
My first pass is a pure PHP solution. Please note this is not production code and I would never push code like this!
<?php /* * - check the Execute Permissions of the upload directory * * - checking file extensions in code using MIME type, which has some drawbacks as it is browser dependant * - added optional ability to restrict file type by extension (.txt) which is easy to extend to other file types - this is more restrictive & therefore more secure * - check size of uploaded file * - would normally move successfully uploaded file to another location (outside the web directory) * */ // max file upload size to be used in script define('FILE_SIZE_LIMIT', 20480); if (isset($_POST['submit'])) { // initialise an empty array to hold errors $errArr = array(); // check to see if the user wants the search to be case sensitive or not $caseSensitive = (isset($_POST['casesensitive']) && $_POST['casesensitive'] == 'on')?'on':'off'; // check to see if the user wants to allow only .txt files, or other text files as well $txtOnly = (isset($_POST['txtonly'])&&$_POST['txtonly']=='on')?'on':'off'; // check for and get the search term if(isset($_POST['searchterm']) && $_POST['searchterm'] != '') { $searchTerm = $_POST['searchterm']; } else { $errArr[] = 'You did not enter a search term'; } // checks for errors and checks that file is uploaded if ($_FILES['uploadedfile']['error'] == UPLOAD_ERR_OK && is_uploaded_file($_FILES['uploadedfile']['tmp_name'])) { // check the file type - this gets the MIME type - not neccessarily the best way to check, esp. for image files!! $fileType = $_FILES['uploadedfile']['type']; // array will make it easier to add other files types later if we want to (csv,htm,html,xml,css,rtf etc) $allowedExtensions = array("txt"); // get the file extension $fileext = strtolower(substr(strrchr($_FILES['uploadedfile']['name'],'.'),1)); // checking the MIME type if ($fileType == "text/plain") { // explicitely checking file extensions and creating a list of "allowed" extensions offers most control / security if($txtOnly == 'on' && !in_array($fileext, $allowedExtensions)) { $errArr[] = "Files with that extension ($fileext) are not allowed!"; } // get the file size $fileSize = $_FILES['uploadedfile']['size']; // check file size if($fileSize > 0) { if($fileSize <= FILE_SIZE_LIMIT) { // read the contents of the file $content = file_get_contents($_FILES['uploadedfile']['tmp_name']); // allow for line-breaks $content = str_replace("\n", "<br />", $content); // we need to have some checks in place on this uploaded content - this would be a start $content = htmlentities($content, ENT_QUOTES); // count number of times search term occurs in content // check to see if the user selected case-sensitive or not if($caseSensitive == 'on') { $searchCount = substr_count($content, $searchTerm); // output the contents of the file with the search term highlighted // below line is "first-pass" which obviously doesn't work with case-sensitive // would naturally replace it later with the final solution - leaving it in place for now... $output = str_replace($searchTerm, '<span class="highlighted-result">'.$searchTerm.'</span>', $content); } else { $searchCount = substr_count(strtolower($content), strtolower($searchTerm)); // below is final solution to case sensitive problem when replacing / highlighting text // output the contents of the file with the search term highlighted $output = preg_replace("|($searchTerm)|Ui", "<span class=\"highlighted-result\">$1</span>", $content); } $output = html_entity_decode($output); } else { $errArr[] = 'That file is too big!'; } } else { $errArr[] = 'That file is empty!'; } $fileName = $_FILES['uploadedfile']['name']; } else { $errArr[] = 'That is not a text file!'; } } else { $errArr[] = 'No file selected or there was an error uploading you file!'; } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Text file upload and Highlight utility</title> <link rel="stylesheet" href="stylee.css" type="text/css" /> </head> <body> <h1>Text file upload and Highlight utility</h1> <?php if(isset($errArr)) // the array is set { if(empty($errArr)) // the array is empty - there were no errors - output the search results { // give info about the search term echo '<h2>Your search term <span class="highlighted-result">'.$searchTerm.'</span> occurred '.$searchCount.' times</h2>'; echo '<p>Search info:</p>'; echo '<ul><li>Name: '.$fileName.'</li><li>Size: '.$fileSize.'</li><li>Case sensitive:'.$caseSensitive.'</li></ul>'; echo '<div id="output">'.$output.'</div>'; } else { foreach($errArr as $msg) // there were errors - output them { echo '<p class="error">'.$msg.'</p>'; } } } ?> <ol> <li>Select a text file</li> <li>Enter a search term</li> <li>Submit to see results</li> </ol> <form enctype="multipart/form-data" action="index.php" method="post"> <fieldset> <legend>Upload text file:</legend> <p><label for="uploadedfile">File:</label><input type="file" name="uploadedfile" /> (limit <?php echo FILE_SIZE_LIMIT; ?>)</p> <p><label for="searchterm">Search term:</label><input type="text" name="searchterm" id="searchterm" /></p> <p><input type="checkbox" name="casesensitive" /> Case sensitive</p> <p><input type="checkbox" name="txtonly" /> .txt extension only</p> <p><input name="submit" type="submit" value="submit" /></p> </fieldset> </form> </body> </html>
See the demo here…