dave1950 Posted April 14, 2014 Share Posted April 14, 2014 I am creating a php search application on a mysql db with three php files: advanced_search.php search_results.php sectiontext.php It works but is awkward, since they open up as separate pages. advanced_search.php contains a form with this code: <form method="post" action="search_results.php?go" id="searchform"> This opens up search_results.php with a list of a summary of search results (document numbers) that are links to the full document text in sectiontext.php, like this: echo '<a href="\ecr/sectiontext.php?ID=' . $FullDocumentID . '">' . $full_doc_number . '</a><br />'; As noted, this all works but is awkward since it changes pages. It would be preferable to have all of this on one page so that the user can easily choose another document or change the search parameters. I am thinking along two lines, but am open to other options if anyone has suggestions: 1. Display all three php files on one web page (i.e., index.php) with includes. I have created the page with the includes, and they are there, but they don’t link to each other when I do the search. They keep opening up new web pages instead of staying on the same index.php page. I am a newbie to php, so still learning about includes. 2. Just put all the code into one php page in different divs and find a way to transfer the variables between steps in the process. This is easy for steps 1 and 2 (form data) but is more difficult for me (as a newbie) for step three (which seems to be more of a master-detail relationship between the search_results list and the sectiontext table. Maybe some javascript to link the selected item on the list to the full document text in step 3? This is just a simple application for myself (not for production), but I would like to make it as good as I can and learn by doing. Any thoughts on how to approach this project? Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/ Share on other sites More sharing options...
mac_gyver Posted April 14, 2014 Share Posted April 14, 2014 you would use a simple page controller to combine and control what the code does on one page. a key to organizing your code to make this easier is to separate your 'business logic' from your 'presentation logic'. see the following example - <?php // the following is the business logic that determines what to do for any page request and gets whatever data is needed $search = isset($_GET['search']) ? $_GET['search'] : ''; if($search){ // get the data to produce the document links // your action code making use of the submitted search term would go here or be included here... // some made up data as an example $links[] = array('id'=>123,'full_document_number'=>'doc 134566'); $links[] = array('id'=>567,'full_document_number'=>'doc 745745'); } $id = isset($_GET['id']) ? $_GET['id'] : 0; if($id){ // get the data/file for the requested document id // your action code making use of the submitted document id would go here or be included here... // some made up data as an example $doc = "some document contents or document link from wherever and however you are storing it"; } // the following is the presentation logic that takes the data from the above business logic and produces a (correctly formatted) html page // the search form if(!$search){ echo 'Enter search term: '; } ?> <form method="get" action=""> search: <input type='text' name='search' value='<?php echo $search;?>'> <input type='submit'> </form> <?php // the document links if($search){ if(isset($links)){ // output document links echo 'Select a document to view:<br>'; foreach($links as $link){ $_GET['id'] = $link['id']; // add document id to (any) existing get parameters $qs = http_build_query($_GET, '', '&'); // build the current url query string echo "<a href='?$qs'>{$link['full_document_number']}</a><br>"; } } else { echo 'No matching documents found.'; } } // the document display if(isset($doc)){ echo 'The requested document:<br>'; echo $doc; } a point about your search form. it determines what will be shown, i.e. gotten, on the page and should use method='get'. Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476037 Share on other sites More sharing options...
dave1950 Posted April 14, 2014 Author Share Posted April 14, 2014 Thanks for your feedback and suggestions. This is just the kind of specific information I need at this early point in the project (and my continuing education). Based on you advice: 1. I have chosed to use a single page for the application. 2. Use the GET method to pass data. I have been doing some research on the "business logic" and "application logic" and I think I understand the rationale and overall concept, but am not sure how to do it with this specific application. Here is the code that I have created based on two of your suggestions (single page with GET method): <HTML><HEAD></HEAD><BODY><h1>Search Form</h1><form method="get" action="search.php?go" id="searchform">Search Term <input type="text" id="" name="searchterm">Document Type <select name="doctype"> <option value="1">Text</option> <option value="3">Background</option> <option value="2">Reports</option> <option value="4">Index</option> </select> <input type="submit" name="submit" value="Submit"></form><h1>Search Results</h1><?$searchterm=$_GET['searchterm'];$doctype=$_GET['doctype']; ?><p>for: <span style="font-size: 14px; font-weight: bold; color: red;"><? echo $searchterm; ?></span> </p><?mysql_connect("xx", "xx", "xx") or die( mysql_error());mysql_select_db("xx") or die(mysql_error());$result1 = mysql_query("SELECTSectionText,FullDocumentID,ReadingNo,SectionTypeID,CONCAT(ReadingNo, '-', SequenceNo) AS full_doc_numberFROM Full_DocumentsWHERE SectionText LIKE '%$searchterm%' AND SectionTypeID = '$doctype'Order By FullDocumentID");$num_records = mysql_num_rows($result1);?><p>documents found: <span style="font-size: 14px; font-weight: bold; color: red;"><? echo $num_records; ?></span></p><?while ($row = mysql_fetch_array($result1, MYSQL_ASSOC)) {$full_doc_number=$row ['full_doc_number'];$FullDocumentID=$row ['FullDocumentID'];echo '<a href="\ecr/search.php?ID=' . $FullDocumentID . '">' . $full_doc_number . '</a><br />';}?><h1>Document Display</h1><?$result2 = mysql_query("SELECTSectionText,FullDocumentIDFROM Full_DocumentsWHERE FullDocumentID = " . $_GET['ID']);;echo "<table border='0' width='800px'> <tr class=\"style3\"> "; while($row = mysql_fetch_array($result2)) { echo "<tr class=\"style2\">"; echo "<td style=\"width: 800px;\"><p>" . preg_replace("/\r\n|\r|\n/", "</p><p>", $row['SectionText']) . "</p></td>";echo "</tr>"; } echo "</table>";?></BODY></HTML> The code does work crudely, but presents two immediate issues: ISSUE 1. When I click on the document number links in the SEARCH RESULTS list, it passes the $FullDocumentID through a GET method to the DOCUMENTS TEXT section by reloading the page and erasing the data in the SEARCH RESULTS list. I would like the list data to remain visible (without having to resort to the browser Back button to reload the search results). ISSUE 2. When the page loads for the first time (before any search or search results are available), there is no $FullDocumentID for the third step, therefore an error message is displayed: “Warning: mysql_fetch_array() expects parameter 1 to be resource, Boolean …” Of course this warning goes away once a link in the SEARCH RESULTS is clicked and the page is reloaded with the document ID in the URL – the GET allows the passing of the ID for the final db query that loads the document text. I would like for the warning statement not to be visible during the first two steps of the search and display process. Just a blank space or perhaps a default document could be loaded when the application starts? Would these two issues be solved by using the business logic/presentation logic model as you have outlined it? Thanks again for your helpful suggestions. Any further guidance is appreciated. Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476053 Share on other sites More sharing options...
mac_gyver Posted April 14, 2014 Share Posted April 14, 2014 the example code i posted contains logic to test if there is a submitted search term before trying to use it and if there is a submitted document id before trying to use it, thereby preventing the errors you are getting. the example also propagates the search term in the document links. i recommend studying the example code again (it's standalone, functional, code that you can run by itself to see how it works.) Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476066 Share on other sites More sharing options...
dave1950 Posted April 14, 2014 Author Share Posted April 14, 2014 Thanks, I really appreciate your patience. Yes, when the example is run as standalone code, with the hardcoded sample data, it does work just fine. I can begin to grasp the concept behind the design principle you are suggesting. In the implementation, I have tried to replace the hardcoded sample data with the working code from my previous efforts as follows: <?php//BUSINESS LOGIC SECTION// get the data to produce the document links$search=$_GET['search'];$doctype=$_GET['doctype'];$search = isset($_GET['search']) ? $_GET['search'] : '';if($search){mysql_connect("xx", "xx", "xx") or die( mysql_error()); mysql_select_db("xx") or die(mysql_error());$links = mysql_query("SELECTSectionText,FullDocumentID,ReadingNo,SectionTypeID,CONCAT(ReadingNo, '-', SequenceNo) AS full_doc_numberFROM Full_DocumentsWHERE SectionText LIKE '%$search%' AND SectionTypeID = '$doctype'Order By FullDocumentID");}$id = isset($_GET['Full_Document_ID']) ? $_GET['Full_Document_ID'] : 0;if($id){// get the data/file for the requested document id$doc = mysql_query("SELECTSectionText,FullDocumentIDFROM Full_DocumentsWHERE FullDocumentID = " . $_GET[$id]);;}// PRESENTATION LOGIC SECTION// the search formif(!$search){echo 'Enter search term: ';}?><form method="get" action="" id="search_criteria">Search Term <input type="text" id="" name="search"></br> Document Type <select name="doctype"></br><option value="1">Text</option> <option value="3">Background</option> <option value="2">Reports</option> <option value="4">Index</option> </select></br> <input type="submit" name="submit" value="Submit"></form><?php// the document linksif($search){if(isset($links)){// output document linksecho 'Select a document to view:<br>';foreach($links as $link){$_GET['Full_Document_ID'] = $link['Full_Document_ID']; // add document id to (any) existing get parameters$qs = http_build_query($_GET, '', '&'); // build the current url query stringecho "<a href='?$qs'>{$link['full_document_number']}</a><br>";}} else {echo 'No matching documents found.';}}// the document displayif(isset($doc)){echo 'The requested document:<br>';echo $doc;}?> I get an error message: "Warning: Invalid argument supplied for foreach() in /home/content/36/10807936/html/ecr/test2.php on line 66" Line 66 is: foreach($links as $link){ I think trying to Get "id" or "$id" from the "FullDocumentID" may be the problem, but don't see any way to fix it based on my current knowledge. Do you see anything obvious that I have missed or distorted? I really do like the way this approach passes the data between the sections without destroying it - it remains visible in the search box and results list - and no Warning message at the beginning of the document display before the search term is provided. So, again, I am thankful for your guidance with this specific project and the way this kind of approach can transfer to future projects once I master it. Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476114 Share on other sites More sharing options...
mac_gyver Posted April 14, 2014 Share Posted April 14, 2014 (edited) after your run the search query, you must loop over the result set and build the $links array from the fetched data. the $links variable in your posted code is the result resource from the query, not the 'generic' data that the presentation logic needs. you should only SELECT the fields you need in that or any query. you are only using FullDocumentID and full_doc_number. these are the only things you should have in the SELECT list in the search query. you would just fetch and store each row to the $links array - // this code expects the result resource from the query to be in $result if(mysql_num_rows($result) > 0){ $links = array(); while ($row = mysql_fetch_assoc($result)){ $links[] = $row; } } btw - Please use the forum's [/nobbc] bbcode tags (the edit form's <> button) when posting code. i would edit your posts, the that generally messes up copy/pasted code that wasn't originally posted in [nobbc] bbcode tags. also, the mysql_ database functions are currently depreciated and will be removed in a future version of php. you should be learning and using either the mysqli or PDO database functions so that you don't need to go through all your code changing the database functions when the mysql_ functions get removed. Edited April 14, 2014 by mac_gyver Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476128 Share on other sites More sharing options...
dave1950 Posted April 14, 2014 Author Share Posted April 14, 2014 Thanks, I put the additional code in the Business Logic section after the first query and I changed it back to $result since that is what is referenced in the new code. When I run the file I get this error message along with the "No matching documents found." Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in /home/content/36/10807936/html/ecr/test2.php on line 24 Search Term Document Type Text Background Reports Index No matching documents found. Here is my latest code. I hope I used the bbcode tags correctly. I have removed the unnecessary fields from the Select statement and will look into PDO. Thanks again for your help. <?php //BUSINESS LOGIC SECTION // get the data to produce the document links $search=$_GET['search']; $doctype=$_GET['doctype']; $search = isset($_GET['search']) ? $_GET['search'] : ''; if($search){ mysql_connect("xx", "xx", "xx") or die(mysql_error()); mysql_select_db("xx") or die(mysql_error()); $result = mysql_query( "SELECT FullDocumentID CONCAT(ReadingNo, '-', SequenceNo) AS full_doc_number FROM Full_Documents WHERE SectionText LIKE '%$search%' AND SectionTypeID = '$doctype' Order By FullDocumentID"); } // this code expects the result resource from the query to be in $result if(mysql_num_rows($result) > 0){ $links = array(); while ($row = mysql_fetch_assoc($result)){ $links[] = $row; } } $id = isset($_GET['Full_Document_ID']) ? $_GET['Full_Document_ID'] : 0; if($id){ // get the data/file for the requested document id $doc = mysql_query( "SELECT SectionText FROM Full_Documents WHERE FullDocumentID = " . $_GET[$id]);; } // PRESENTATION LOGIC SECTION // the search form if(!$search){ echo 'Enter search term: '; } ?> <form method="get" action="" id="search_criteria"> Search Term <input type="text" id="" name="search"></br> Document Type <select name="doctype"></br> <option value="1">Text</option> <option value="3">Background</option> <option value="2">Reports</option> <option value="4">Index</option> </select></br> <input type="submit" name="submit" value="Submit"> </form> <?php // the document links if($search){ if(isset($links)){ // output document links echo 'Select a document to view:<br>'; foreach($links as $link){ $_GET['Full_Document_ID'] = $link['Full_Document_ID']; // add document id to (any) existing get parameters $qs = http_build_query($_GET, '', '&'); // build the current url query string echo "<a href='?$qs'>{$link['full_document_number']}</a><br>"; } } else { echo 'No matching documents found.'; } } // the document display if(isset($doc)){ echo 'The requested document:<br>'; echo $doc; } ?> Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476136 Share on other sites More sharing options...
mac_gyver Posted April 14, 2014 Share Posted April 14, 2014 the error message is because your query failed due to an error (you removed the comma between the two remaining items in the SELECT list.) you also don't have any error checking logic for your queries, so you are getting follow-on errors when they fail due to an error in them. Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476137 Share on other sites More sharing options...
dave1950 Posted April 15, 2014 Author Share Posted April 15, 2014 I inserted a comma in the Select statement like this: $result = mysql_query("SELECTFullDocumentID,CONCAT(ReadingNo, '-', SequenceNo) AS full_doc_numberFROM Full_DocumentsWHERE SectionText LIKE '%$search%' AND SectionTypeID = '$doctype'Order By FullDocumentID");} but got the same error message as before when the page loads. Interestingly, if I type in and submit a search term that I know to be in the documents, the error message goes away and the text below the form reads: "Select a document to view:" No error message, but no items in the list either. The search term was "migraine" (it's a medical database) and the end of the url after submitting the form was "... test.php?search=migraine&doctype=1&submit=Submit" So apparently the passing of the variables via Get is working. Any further thoughts? Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476142 Share on other sites More sharing options...
mac_gyver Posted April 15, 2014 Share Posted April 15, 2014 line 20 of your last posted code is the end of your if($search){ ... } logic. however, lines 22-28 are part of that logic. the closing } on line 20 needs to be moved down. Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476157 Share on other sites More sharing options...
dave1950 Posted April 15, 2014 Author Share Posted April 15, 2014 I moved the } down as you suggested and there is no error message when the page loads, so that is resovled. But the search results are still blank with the variables from the form input visible in the url as before. Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476165 Share on other sites More sharing options...
mac_gyver Posted April 15, 2014 Share Posted April 15, 2014 at this point, these problems are logic, copy/paste, and typo errors on your part. you need to debug what your code is doing and try and solve these yourself. it would probably help if you set php's error_reporting to E_ALL and display_errors to ON to get php to report and display all the errors it detects. Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476166 Share on other sites More sharing options...
Solution dave1950 Posted April 15, 2014 Author Solution Share Posted April 15, 2014 Thanks for helping me create a solid conceptual design foundation that I can work with moving forward. I will now focus on learning about debugging and error reporting, and once this basic phase is working add refinements such as pagination, highlighting text, etc. Quote Link to comment https://forums.phpfreaks.com/topic/287749-search-application-design/#findComment-1476174 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.