Jump to content

-Mike-

Members
  • Posts

    14
  • Joined

  • Last visited

    Never

Profile Information

  • Gender
    Not Telling

-Mike-'s Achievements

Newbie

Newbie (1/5)

0

Reputation

  1. In your queries. Yikes! $_POST That's trusting people to be good! You could put anything you like into the email field, and it'll run a query based upon that. It's called "sql injection", and your vulnerable. Escape anything that use to query a database that is got from anywhere at all - so page numbers, article ids... usernames. $email = mysql_real_escape_string($_POST['email']); Then use $email in the query. Personally I first do a regex against emails to check their format, if it's okay - then I will do the mysql_real_escape_string and search the database. No point doing a search on something that's not going to be there in my opinion You crypt the passwords entered value, but for "good practice" i think you should also do the same there: $crypt_pass = mysql_real_escape_string($crypt_pass); No doubt more knowledgeable people will give better advice, or more complete advice, where applicable (or correct me where wrong).
  2. Right, so OOP isn't exactly new to me. However, applying it to a website is kind of new, and I'm wondering if I am doing this correctly or not. Is it un-necessary, have I got "good practice" going (sorry for some layout inconsistencies, tried to make it so you don't have to scroll horizontally to see all content! - all code works) Basically, I am not sure about it. I'm hoping that someone has the patience to sit through reading it all. The application is not important at this time, just a concept idea - throwing together something like a concept at this point. The idea is that people will visit a web page, enter their post code into a form, and click "okay". This will then: 1) Check the post code is valid. If not, redisplay the page with their entered details, and also what is wrong with their codes (incorrect format etc) 2) Check whether the (valid) post codes are covered. If so, then it outputs a message that they have coverage by re-presenting the page with this message and the form with their code in again. or Checks the code, finds no coverage, and outputs the page again with an apology message, but the option to receive an update when the coverage is in their area. Anyway, two classes to give an example. A "Page" class, and a "Coverage" class. There are more classes involved, header is just the page header s- like <html><title> $title</title> etc Footer is the same, but with a default footer message, menu has a default html menu. Database is just a query method, abstracts the connection responsibilty and actual method of query to the class, so that its type (mysql) can be changed without affecting any other class. <?php require_once 'Header.class.php'; require_once 'Footer.class.php'; require_once 'Menu.class.php'; /** * Class representing the page, although the page has NOT been abstracted down into classes representing the actual content boxes, or * sides of the page themselves... just a basic representation. * Could do with some extra work in the near future. * */ class Page{ var $header; //Holds html content for a page header, including meta tags var $left; //The left side of the page overall. var $right;//the right side of the page. var $leftbox;//array for items to display in left. var $rightbox;//array for items to display on the right. var $main;//The main. var $footer; //the footer message to the page. var $breadcrumb; //the pages breadcrumb. function Page(){ //Footer, static class method returns default footer for every page. $this->footer = Footer::$footer; / $this->leftbox = array(); $this->rightbox = array(); } /* * @param $title, the title of the page to be displayed, displayed in the browser bar * @param $metaKey, the meta keywords for the page to be displayed. Default value available. * @param $metaDesc, the meta description words for the page to be displayed. * * */ function setHeaders($title = "", $metaKey = "", $metaDesc = ""){ //Create a new Header object, with the given title, meta description and keywords. $head = new Header($title, $metaKey, $metaDesc); //Set the header to be the HTML text returned by the getHeaders function $this->header = $head->getHeaders(); } /* * Function to set the breadcrumbs value. * @param $crumb - the html code of links for the breadcrumb. * */ function setBreadCrumb($crumb){ $this->breadcrumb = $crumb; } /* * Allows the user to add a content box to the right hand side of the page. * Will add the page format for content, so into a rounded edged "box" on the page. * @param $content - the html content of the right hand side "box" to be added */ function addRightBox($content){ $this->rightbox[] = '<div class="top"></div><div class="middle">' . $content . '</div><div class="bottom"></div>'; } /* * Allows to add a header to the right hand side page, which will not have the content box added * @param $content - just the text to be displayed as a title on the page, without any box formatting. */ function addRightTitle($content){ $this->rightbox[] = '<div class="title">' . $content . '</div>'; } /* * Allows the user to add a content box to the left hand side of the page. * Will add the page format for content, so into a rounded edged "box" on the page. * @param $content - the html content of the left hand side "box" to be added * @param $logo - the class (text) value for the box top (basically allows to change logos to pre-determined css ones at will) */ function addLeftBox($content, $logo = ""){ if($logo == ""){ //if no logo specified, go with the default. $this->leftbox[] = '<div class="topthin"></div><div class="middle">'. $content . '</div><div class="bottom"></div>'; } else { //otherwise, allow the top to display the corresponding logo. $this->leftbox[] = '<div class="'.$logo.'"></div><div class="middle">' . $content . '</div><div class="bottom"></div>'; } } /* * Allows the user to add something to the left hand side as it is. * This should only be used when the code for the format is added * Otherwise, addLeftBox should be used to maintain the layout as required. */ function addLeft($content){ $this->leftbox[] = $content; } /** * Function allows to add errors to an error box on the left side of the page. * @param $content - the basic html formatted text for the errors. */ function addErrorLeftBox($content){ $this->leftbox[] = '<div class="topError"></div><div class="middleError"> ' . $content . '</div><div class="bottomError"></div>'; } /* * This should ONLY be used when the layout is controlled by the calling class * (as in FAQ, left side layout is dependant upon the page * specifically, and therefore it has it's own layout defined). * Otherwise, it should be controlled by using the addLeftBox function. */ function setLeft($content){ $this->left = $content; } /* * This should ONLY be used when the layout for the right hand side is controlled by the calling class entirely. * Otherwise, the addRightBox function should be used. * */ function setRight($content){ $this->right = '<div id="right"><div id="breadcrumb">' . $this->breadcrumb . '</div>' . $content . '</div>'; } /* * Creates the "left" div of the page, by iterating over all the boxes contained, * outputting the overall left hand side. * Essentally wraps all "leftbox" items into the left div, ready for display. * Once done, cannot be undone. */ private function compileLeft(){ $this->left = '<div id="left">'; foreach($this->leftbox as $key => $value){ $this->left .= $value; } $this->left .= '</div>'; } /* * Creates the "right" div of the page, by iterating over all the boxes contained * outputting the overall right hand side. */ private function compileRight(){ $this->right = '<div id="right"><div id="breadcrumb">' . $this->breadcrumb . '</div>'; foreach($this->rightbox as $key => $value){ $this->right .= $value; } $this->right .= '</div>'; } /* * Compiles the two sides of the page, dependant upon whether the setLeft/setRight functions * have been used, * or whether the addBox has been used. In instances where both used, * the set functions will have priority (ie over-ride) * the add functions... */ private function compilePage(){ if(!isset($this->left)){ $this->compileLeft(); } if(!isset($this->right)){ $this->compileRight(); } $this->setMain($this->left . $this->right); } /* * Function sets the main content of the page. Assigns the top menu, and inserts page * contents between the content divs * Adds the banner and menu to the main page. * Constructs the page body, the left and right contents are added together in a content div * which is contained within the main div. * The menu is also added to the page body at this time. */ private function setMain($main){ $this->main = '<body><div id="main">' . Menu::$topMenu . '<div id="content">' . $main . '</div>'; } /* * Compiles the page, and returns the html to be output. */ function returnPage(){ $this->compilePage(); return $this->header . $this->main . $this->footer; } } ?> The coverage class, which utilises the page class, along with database classes (just has a query and a cleaning function, whereby does a mysql_real_escape_string on the passed variable, and returns it). <?php //Require Database class, as per usual require_once 'Database.class.php'; //The validating class require_once 'Validator.class.php'; //The class that creates pages. require_once 'Page.class.php'; /** * Evaluates whether a supplied post code is covered or not in the service. * Will check postcodes using the validator class. * Constructs a page utilising the Page class, setting values for the parts of the page. * * */ class Coverage { var $left; //The left side of the page. var $right;//The right side of the page. var $title;//Page title. var $connection;//The db reference here. var $validator; //The validator reference here. var $breadcrumb; //html for the breadcrumb. var $page; //reference to the page object. function Coverage($first = null, $second = null){ //initialise the few objects required first - the page and database connection. $this->page = new Page; $this->connection = new Database; $this->page->setHeaders("Coverage", "", ""); $this->page->addRightBox('Text'); //Set the breadcrumb to have a link to the home page, this is default, others may be added //later (wrapped in the page class) $this->breadcrumb = '<a href="index.php" title="Home">Home</a> > '; //Check if there are some parts to the post code. if(isset($first) && isset($second)){ //We need a validator, construct one now. $this->validator = new Validator; //Validate the entered post code parts $er1 = $this->validator->validateFirstPostcode($first); $er2 = $this->validator->validateSecondPostcode($second); //Were there any errors in the validator (indicating errors with the codes). if($this->validator->numErrors() > 0){ //There were errors in the checking, so we need to re-display with the errors //displayed somewhere... //Use the validators "getDisplayableErrors" (html formatted error messages), //and add them to the left side of page. $this->page->addLeftBox($this->validator->getDisplayableErrors(), "error"); //Display back the input box, wih the values entered by user. $this->page->addLeftBox($this->getInputBox($first, $second, $er1, $er2), "coverage"); //Set some right side of the page text. $this->page->addRightBox("Just sample text"); } else { //No errors found, all okay - query the db to find a match for their entry. $num = $this->getResultCode($first, $second); //returned value is 0, then no matches. If it's any other number - //it's the number they contact... if($num){ //If there is a "num" set, then the post code entered is covered, //they need to contact this number sent. $this->page->addLeftBox($this->getMessage($num), "covered"); } else { //if there is not, then we don't have cover. Display the "coming soon" //version instead (pre-set message). $this->page->addLeftBox($this->getMessage($num), "soon"); } //Add the normal input box to the page, so they can check another post code //(includes their entered values). $this->page->addLeftBox($this->getInputBox($first, $second), "coverage"); } } else { //No post code submission existed, so display the default page instead. $this->page->addLeftBox($this->getInputBox(), "coverage"); } } /** * Method to add to the breadcrumb... * */ function breadCrumb($crumb){ $this->breadcrumb .= $crumb; } /* * Function returns html text of the input box for users to input their post code details. * @return $input - the HTML text that will construct the input box required. */ function getInputBox($first = "", $second = "", $er1="1", $er2="1"){ $input = '<div class="inputbox"><form id="form2" name="form2" method="post" action="coverage-map.php"> <div class="title"><b>Am I Covered?</b></div> <span class="label"><label>Postcode:</label></span> <span class="divs"><input class="input'.$er1.'" name="First" type="text" id="First" size="2" maxlength="4" value="'.$first.'"/> <input type="text" class="input'.$er2.'" name="Second" id="Second" size="1" maxlength="3" value="'. $second .'" /></span> <span class="divs"><input name="IntSub" type="submit" id="IntSub" value="Check" /></span> </form></div>'; return $input; } /** * Method takes the number given, and according to whether it's a 0 (false) or a positive value, *will * then alter the message that gets returned. * */ function getMessage($num){ if($num){ $str = "Coverage available, text your postcode to " . $num . " to initiate registration process"; } else { $str = "Coverage is not yet available in your area. Text your postcode to 656565 to be alerted when coverage is available"; } return $str; } /* * Function that takes both parts of a post code (should have been pre-checked for *correctness on format) * The postcode used will be checked against the database to check coverage. * @param $first - the first section of postcode * @param $second - the second part of the postcode. * @return $num - numerical value representing the number users will text to sign up on. * If the postcode wasn't covered, will return 0. */ function getResultCode($first, $second){ //Set up the return value to be 0 at the start (also evaluates to false in a if statement, //which is why chosen) $num = 0; //Firstly, "clean" the input to avoid sql injection attempts. $first = $this->connection->clean(strtoupper(trim($first))); $second = $this->connection->clean(strtoupper(trim($second))); //Run query with the cleaned input $result = $this->connection->query("SELECT * FROM PostcodeMapping WHERE PostcodeArea = '" . $first ."'"); //Check if the result shows we cover this area. if($this->connection->numRows($result) > 0){ //If covered, we need to obtain the code number that people will need to text into the business. //Get the value that the users will have to text. while($res = $this->connection->fetchArray($result)){ $num = $res['TextNum']; } } //Now to return the value that was found. This will either be the mobile phone number found by the query, or alternatively it will be the //value of 0, which will indicate that the postcode wasn't covered. return $num; } /** * Calls the Page objects returnPage method, which will return a string of the html of the page. * @return String - string of the page's html to output. */ function returnPage(){ return $this->page->returnPage(); } } ?> Essentially, when you visit the "coverage.php", this is it's code: //we require the specific classes require_once 'classes/Coverage.class.php'; $coverage = new Coverage($_POST['First'], $_POST['Second']); echo $coverage->returnPage(); Creates the Coverage class, passing the "post" variables (may or may not exist of course). Echo's out the html of the page the class makes. So, my query is whether I am actually doing things in a reasonably effective manner, or whether my attempted use of Objects in the design is both poor and weak. I know I can do things proceedural - but if I wanted to do proceedural, I would have used proceedural. I want to have it OO, and now I wish to find out whether I'm doing okay, or poorly. ANY suggestions or hints/tips are really appreciated, as is your time if still reading at this point Tried searching these things via Google, but tutorials tend to be of vastly differing quality. Furthermore, classes may already exist for some things I am trying to do, but I am trying to learn myself, not just learn how to use others stuff - but get good principles etc. Bit long winded there, apologies
  3. Is thorpes "LIMIT 1" so that when the first matching result is returned (should also be the only one in the table) it stops, erm, querying the rest of the table right there? ie, if it starts at the beginning in a DB of 1000 users, and the match is number 5 - it only goes through 5 rows before stopping due to the limit, whereas without the limit - it'd find the match on 5 yet continue through the lot? I always assumed it'd stop anyway, so clarification/correction of my viewpoint would be much appreciated thanks! Am also building something similiar, although my code is different (have a db class, have a login class, have a "page" class). It's tough trying to find out whether your method is good/bad
  4. Thank you for that, I had gone through the api but obviously missed that one - whoops
  5. Firstly I am not that familiar with php, and not much of a "programmer". I have a (hopefully) quick/simple question. Is there a function which means you can insert a value to the start of array? I know I can achieve it by using an array_reverse, followed by adding the desired first element to the end, followed by another array_reverse - but wondering if there is a simpler/quicker way of doing this? Many thanks for any input. (snippet of what I mean, using array_reverse though). Have an array of 1, 2, 3 as values - want to put 0 in the first position... $ar = array("1","2","3"); $ar = array_reverse($ar); $ar[] = "0"; $ar = array_reverse($ar); would give: 0 1 2 3 (No, I haven't tested that code, just written it for an example).
  6. Many thanks for the input guys, reassuring to know that it's basically as good as it can be.
  7. Essentially I am working on a web project. At present there is a database table which will hold post codes. These post codes will represent areas that their service covers. So if a postcode appears in the table, it's somewhere that they can deliver their product to. Obviously, if someone wants a service - they'd like to know whether it can be provided to them - so we will search the table for their postcode, and provide an answer as to whether they are covered or not (then they may sign up). Whether it gets us anywhere remains to be seen. However, their previous coder created the database as seen below. Currently it holds very little info (testing only) - about 25 entries. CREATE TABLE postcodes ( id INTEGER AUTO_INCREMENT PRIMARY KEY, start VARCHAR(4), end CHAR(3), ); As it stands, a postcode (for example, SW1 4EN) would have SW1 in the start, and 4EN in the end column. If we have SW1 2UV - we then have another row with SW1 entered in the start, and 2UV in the end. If another SW1 was added, we have a third row with SW1 and then the end value of whatever. So the "start" column will hold many duplicates. SW1 4EN SW1 2UV SW1 6JH Personally this seemed wasteful. However, linking SW1 to another table which then held all the ending parts would result in a huge amount of database tables as far as I know - around 2840 or so (for all post codes in the UK). Naturally chances of it being that large are slim, but certainly several hundred tables would be a possibility! That seems a bit "mad" when I thought of it like that... but is that the best design? Also, considering it's current structure - there is no advantage that I can see beyond having (for example) just a single column of "SW1 4EN" or "SW14EN" instead. I assume the "start" and "end" are useful because you may search for SW1 to see all areas covered within that post code (ie return all end values for matching start value), so therefore its better than having a single column which sticks teh two together (eg column postcode, varchar( - entry value like "SW12 4EN" - which means you cannot search for SW12 post codes, as you'd need to go through each entry and "split" it to match the first four characters. I'm not very experienced with designing database tables. Usually I have no issue whatsoever in creating tables for people, and linking them to records etc - but this table I am a bit baffled about how best it should be structured. Bearing in mind that currently the table could have 2840 different "start" entries - and that each start entry may be repeated several times to different end entries, I foresaw some searches requiring a lot of iterations - eg, someone types in the first part of a post code, we then have to run a query where start = "SW1" and return all the "end" values, to then get the unique ID. I hope this isn't too jumbled or muddled, I'm confused as to what's best in this instance! Any suggestions from experienced designers would be gladly accepted, as I wish to make this table the best it can be (primary use will be for searches, which may be carried out fairly frequently. However, new postcodes may be added as well). Thanks to anyone who can offer some advice, and sorry that this may seem trivial to some.
  8. Are you sure about the location of the error? Seeing as connection simply returns a false if not successful, have you checked whether it actually has a connection for you to execute a query upon, or just trusting that it's all okay? From the manual: [code] <?php $mysqli = new mysqli("localhost", "my_user", "my_password", "world"); /* check connection */ if (mysqli_connect_errno()) {   printf("Connect failed: %s\n", mysqli_connect_error());   exit(); } ?> [/code]
  9. [quote][code]$price = $_POST["price"]; $query = "SELECT * FROM client WHERE price LIKE '%".$_POST['search']."'";[/code][/quote] Maybe do a slight change: [code] $price = $_POST["price"]; $query = "SELECT * FROM client WHERE price BETWEEN '$price'-1000 AND '$price' + 1000"; [/code] The above shows selecting price from the search criteria - but isn't the criteria the price, at which point shouldn't it be the price that is matching the value in the price column? An alternative, apart from a fixed price, is to have a range for each customer... or a percentage variable of the price instead (ie 200,000 +- 10%, so 180-220,000). I just added (not sure about syntax on it) the ability to check between two prices based upon the clients stated price, plus or minus 1000. As I said, don't quite get why you match their price column with your search result... shouldn't it be your search result brings up a price, which customers are then matched against that price?
  10. [quote author=akrytus link=topic=104643.msg417496#msg417496 date=1155830237] I need the PHP command to download a file via FTP to the clients local drive.  I thought it was ftp_fget or ftp_get, but they only save to the server side current web directory.  [/quote] Strange... http://uk.php.net/manual/en/function.ftp-get.php Those indicate that it downloads to the current clients machine to me? Any verification?
  11. [quote author=nelquintin link=topic=104636.msg417495#msg417495 date=1155830195] My testing box is nt connexted to any server so it doesnt make a dirrence. If i pull up a property i want to match all my clients in another table with that property the foreign key would be price i think?Should i have a min and max price for my clients? [/quote] In that case, once you've found your property, I don't quite see where the value of "price" comes from when passing it onto the next php page? You only have a submit button and nothing else (really), but nothing that actually passes the needed variables of price and search onto the next page for processing your next query. [code] <form method="POST" action="matchclient.php"> <input type="Submit" name="Submit" value="Match Client"> </form>[/code] In which case, if you add a hidden field: [code] <form method="POST" action="matchclient.php"> <input type="hidden" name="price" value="<?php echo $price; ?>" /> <input type="hidden" name="search" value="<?php echo $search;?>" /> <input type="Submit" name="Submit" value="Match Client"> </form> [/code] Then when you hit the submit button to pull up your clients, both price and search will have values... Otherwise it looks like your next search (to find the clients based upon the property you've found) are attempting to match, well, no value as far as i can see - as it doesn't currently exist as a posted variable on that submit button.
  12. [quote author=Jenk link=topic=104636.msg417474#msg417474 date=1155828804] It most definately does need escaping. [/quote] Remarkably clear on your correction - WHICH part :P I be assuming it's: [code] %".$_POST['search']."'";[/code] I was going off the fact that it's acceptable to have put in: '$var' to your sql coding without any hiccup, and simply went with that. As it was, I still question whether he was wanting to search only the end of their fields for the search value, or anywhere in there..
  13. A few things i thought, but may not be right: you are searching to match price field to $_POST['search'] and not $_POST['price'] or something similiar? Your while loops should specify mysql_fetch_array($result, MYSQL_ASSOC) - because you then use the name of the fields in the database to reference your fields. My memory doesn't remember if it does this automatically or not though... [code] hile ($row = mysql_fetch_array($result)) {         $picture = $row["picture"];         $minprice = $row["minprice"];       $maxprice = $row["maxprice"];       $price = $row["price"];         $ref = $row["ref"];         $type = $row["type"];         $erf = $row["erf"];         $size = $row["size"];         $bed = $row["bed"];         $bath = $row["bath"];         $gar = $row["gar"]; [/code] Your image: [code]echo "<image src=\"$picture ","\" style=\"border: 2px solid black;\">[/code] is incorrectly escaped for quotations: [code]echo "<image src=\"$picture \" style=\"border: 2px solid black;\">[/code] [code] $query = "SELECT * FROM propertys WHERE ref LIKE '%".$_POST['search']."'";[/code] Doesn't need to escaping there - [code] $query = "SELECT * FROM propertys WHERE ref LIKE '%$_POST['search']%' ";[/code] I added an extra % sign in, otherwise you are searching for things ending in the value of $_POST['search'] Finally, just for testing, i'd make that if(mysql_num_rows($result)) into if(mysql_num_rows($result) > 0){ instead... i seem to remember it giving me problems at one point :/
  14. An assumption about your checkboxes on your form is as follows: [code] <input type="checkbox" name="id[]" value="CourierPrimaryKey"/> [/code] Of course, the courier primary key will also identify the correct contact... So when submitting the form, you will be passing an array. The first bit is to get your values from the form and shove them into the array: [code] $array = $_POST['id']; [/code] Then we need to loop through that array, query the database for the contacts email address/name and then send them the generic email (with added bits); [code] foreach($_POST['id'] as $id){ //loop through the array $sql = mysql_query("SELECT * from CONTACTS WHERE CourierId = '$id'"); //run query to get the contact $row = mysql_fetch_array($sql, MYSQL_ASSOC); //get the row. $subject = "Dear " . $row['contactName'] . ", rest of title"; $body = "Dear " . $row['contactName'] . ", We wish to let you know and the rest of body"; mail($row['emailaddress'], $subject, $body, "FROM: myemail@email.com"); } [/code] That's pretty basic, no error checks etc at all. Important parts: Your form: [code] <form name="myname" method="post" action="process.php"> <input type="checkbox" name="id[]" value="1"/>One<br /> <input type="checkbox" name="id[]" value="2"/>Two<br /> <input type="checkbox" name="id[]" value="3"/>Three<br /> <input type="checkbox" name="id[]" value="4"/>Four<br /> <input type="checkbox" name="id[]" value="5"/>Five<br /> <input type="checkbox" name="id[]" value="6"/>Six<br /> <input type="submit" value="submit" name="submit" /> </form> [/code] Those, when submitted, would give an array containing the values of the selected items. To get the array, in teh process.php (or where-ever it's being processed to) [code] $variable = $_POST['id']; [/code] Now your $variable variable is holding an array. Looping through this array: [code] foreach($variable as $item){ //code to execute in each loop here } [/code] You can reference each value/object in your array by stating $item. [code] foreach($variable as $item){ echo $item . "<br />"; } [/code] That would print out the value of each item in the array with a line break between them. This is how we email them, so we do a query to get EACH couriers contact details from the database during a loop. Each loop will stick the value of the next item in the array into the variable of $id, which we then use during a query to the database. [code] foreach($_POST['id'] as $id){ $sql = mysql_query("SELECT * FROM TABLENAME WHERE courierId = '$id'"); //the query $row = mysql_fetch_array($sql, MYSQL_ASSOC); //fetch row, which we can get each field via it's name! } [/code] Using the $row, we can reference each query result's fields to get their values, so if you have a field called email storing the email address in the contacts database, you can say $row['email'] to get it's value. Therefore, you can use the mail function of php (php.net, type mail into the seach box) with their email address returned from the query, and send the message to them. Each loop will do this until it has gone through all the values from your form. If this isn't explained very well, or is confusing, please let me know ;)
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.