Jump to content
Larry Ullman's Book Forums

Stuart

Members
  • Posts

    141
  • Joined

  • Last visited

  • Days Won

    12

Everything posted by Stuart

  1. Hi Hartley no worries - happy to explain my reasoning. So this is the code from Chapter 2: // Determine what page to display: switch ($p) { case 'about': $page = 'about.inc.php'; $page_title = 'About This Site'; break; case 'this': $page = 'this.inc.php'; $page_title = 'This is Another Page.'; break; case 'that': $page = 'that.inc.php'; $page_title = 'That is Also a Page.'; break; case 'contact': $page = 'contact.inc.php'; $page_title = 'Contact Us'; break; case 'search': $page = 'search.inc.php'; $page_title = 'Search Results'; break; // Default is to include the main page. default: $page = 'main.inc.php'; $page_title = 'Site Home Page'; break; } // End of main switch. Now if you want to modularise the admin modules too you'll need to add in a series of other options (e.g. change password, manage users, manage news) if you added those in you'd have to conditionally check for the user_id variable in the session on each case. This creates code repetition (think DRY) and makes for (at least in my opinion) messy code. Doing that would look like this: // Determine what page to display: switch ($p) { case 'about': $page = 'about.inc.php'; $page_title = 'About This Site'; break; case 'this': $page = 'this.inc.php'; $page_title = 'This is Another Page.'; break; case 'that': $page = 'that.inc.php'; $page_title = 'That is Also a Page.'; break; case 'contact': $page = 'contact.inc.php'; $page_title = 'Contact Us'; break; case 'search': $page = 'search.inc.php'; $page_title = 'Search Results'; break; case 'change': if (isset($_SESSION['user_id'])){ $page = 'change.inc.php'; $page_title = 'Change Password'; break; } case 'manage': if (isset($_SESSION['user_id'])){ $page = 'manage.inc.php'; $page_title = 'Manage Users'; break; } case 'user': if (isset($_SESSION['user_id'])){ $page = 'user.inc.php'; $page_title = 'New User'; break; } // Default is to include the main page. default: $page = 'main.inc.php'; $page_title = 'Site Home Page'; break; } // End of main switch. Now you could do the check first and present two different switch statements but that again causes code repetition. To achieve the exact same as the above code block using my technique requires: $include = 'main.inc.php'; $page_title = 'Site Homepage'; $anyone = $logged_in = array(); $anyone['about'] = 'About this site'; $anyone['this'] = 'This is another page'; $anyone['that'] = 'That is Also a Page.'; $anyone['contact'] = 'Contact Us'; $anyone['search'] = 'Search Results'; $logged_in['change'] = 'Change Password'; $logged_in['manage'] = 'Manage Users'; $logged_in['user'] = 'Add User'; $pages = isset($_SESSION['user_id']) ? array_merge($anyone, $logged_in) : $anyone; if (array_key_exists($_GET['page'], $pages)){ $include = $_GET['page'] . '.inc.php'; $page_title = $pages[$_GET['page']]; } To me the second option is easy to read/maintain, conforms to the DRY principal, is more portable and shorter (which in general I prefer as long as it doesn't sacrifice readability/flexibility). I appreciate it doesn't make a big difference and going with the switch statement is perfectly fine but I hope that at least illustrates why I presented that as an idea/technique - what are your thoughts?
  2. At the moment to prevent people trying to include files that do not exist you're using the switch statement and then inside that you'd have to check if they are logged in or not to decide whether they have access to that particular page. The way I'd do it is like so: $anyone = array('page_a', 'page_b', 'page_c', 'page_e'); $logged_in = array('page_d'); $pages = isset($_SESSION['user_id']) ? array_merge($anyone, $logged_in) : $anyone; $include = in_array($_GET['page'], $pages) ? $_GET['page'] . '.php' : 'index.php'; include($include); The code basically establishes 2 arrays (one all the content that anyone can see and one for content that only logged in users can view). Then it creates a master lookup array containing the content that should be available to that user. Next we check if the page submitted exists in the $pages array and if so we save the value ready for inclusion - if not we include the default index include. Just incase you're not familiar with the ternary operator: $pages = isset($_SESSION['user_id']) ? array_merge($anyone, $logged_in) : $anyone; Is the same as: if (isset($_SESSION['user_id'])){ $pages = array_merge($anyone, $logged_in); } else { $pages = $anyone; }
  3. Hi Theo, I think we're going to need a little more information to get a solution - I'm not even entirely sure what's problem we're trying to fix. Explain what you're trying to achieve (desired outcome) and what's actually happening at the moment (current outcome). If you're saying the result of that inserted rows check is FALSE then add: echo mysqli_error($dbc); in the else clause. Also as per the forum rules provide your PHP and MySQL versions so you can get accurate and timely responses.
  4. $string = 'the quick brown fox jumps over the lazy dog'; $words = explode(' ', $string); $emphasise = FALSE; foreach($words as $key => $word){ if ($emphasise){ $words[$key] = '<strong>' . $word . '</strong>'; } $emphasise = !$emphasise; } echo implode(' ', $words);
  5. I think by Larry was talking about if you want to print the image off on paper then it's not a PHP issue. You still need to use PHP to query the database and to store the image. To store the important part is to convert to binary format which basically means using: file_get_contents(); To display it you can use something like: echo '<img src="data:image/png;base64,' . $row['image'] . '">';
  6. Slightly annoyingly I've already written this post once and accidentally pressed refresh so apologies if it's not overly thorough! Thanks for sharing your code its always interesting to see how other people code as my experience thus far is Larry's books or my own. In the main I like the concept and the way you've gone about it - if you don't mind though I've noticed a few things that could be improved. 1) You've used the global keyword to provide functional level scope to all your variables. Global should only really be used to provide access to variables that do not change from call to call e.g. a database connection. With variables like yours it would be better practice to pass them as arguments to the function. 2) You declare $day_after inside print_event but the variable is never used. 3) I think the process of getting the 1st Sunday of the next September (I have got that right haven't I?) is a little long winded. You could achieve the same with: if (($ts = strtotime("sunday 0 september")) < time()){ $ts = strtotime("sunday 0 september next year"); } Then to get the variable to plug into the date_in_words function just use: -1998 + date('Y', $ts); Hope you don't mind me bringing those things up - their only minor things but they make a nice concept a little more elegant.
  7. Sorry I don't really understand exactly what you're trying to ask but I think the index you're looking for is tmp_name NOT temp_name?
  8. I think you've missed the point of Larry's post the stored procedure isn't working (probably due to some kind of syntax error) to find out why (like Larry suggests) uncomment the debugging line and the script will tell you why it doesn't work.
  9. This is not the problem - is this the actual line you're using? $current_poll = ('Y' . "-" . 'm' . "-" . '01'); Because that won't produce a date unless you use the date function like: $current_poll = date('Y-m-01'); And then this will work: $select_poll = "SELECT P.poll_id, P.question, A.answer_id, A.answer FROM poll_questions P INNER JOIN poll_answers A ON p.poll_id = A.poll_id WHERE P.date = '$current_poll'";
  10. Yeah was a little worried at the time HartleySan that it wasn't the clearest explanation but was putting off writing the code as I've got too much work at the moment. A simpler way and kind of a hybrid between our suggestions might be to divide your dataset by the number of staff. Then query at each of these points e.g. at 50, 100, 150, 200 and get the first letter of that ticketers last name (have to order by last name obviously) and that creates you bands. It's not as effective at normalising the sizes of the lists as my first approach but it's a lot simpler. But like HartleySan says if you have to print the lists off anyway (probably with page breaks at each letter to make it easier for the staff) you could just hand out the paper equally amongst them.
  11. I'd set some limits based on the dataset - basically divided the total number of attendees by the number of staff you have working. Then run a query that counts the number of rows in a group and group that by the first letter of the last name. Initialise a counter variable, then loop through all the results progressively checking if the limit has been reached and if not adding the next value onto the variable. At the same time add the current letter to an array. Once you reach the limit - reset the counter and create a new array (or sub-array) to hold the next series of letters and repeat the process. You might want to consider setting tolerance bands so if the cut off is 500 you don't add on when you're on 499. Or you might want to check the amount before you add it on to ensure its not going to send you significantly over. That all make sense?
  12. Just for completeness let me explain re: changing the price submitted from the client side. It would be relatively easy - in it's simplest form create a HTML page with the same structure and form action as the page in question and simply alter the prices. I guess this attack would be foiled by the use of a form nonce however intercepting a HTTP request with a proxy like BURP, modifying and submitting it would also be pretty straight-forward. Again if these prices aren't part of a e-commerce system it's not a major consideration.
  13. First off I appreciate if you're learning you want to make everything dynamic and do it with PHP but to do exactly what you want 100% dynamically is quite difficult - especially when (if I understand correct) the value will only change once every year? If that's the case you might want to compromise by simply creating an array with the timestamp as the key and the string to output as the value. That way you could could just look for the lowest key greater than the current timestamp and output it. You could quickly populate the next 10, 15 or 20 years and not have to worry about anything too complex. I don't know of and can't think of any simple dynamic way to convert from 13 to thirteen - you could do would be 13th either using a series of logic operators based on the day or a combination of mktime() and date() using the S formatter. If you wanted to dynamically calculate the first Sunday of the next September you can use the strtotime() function - although I'm sure I've run into problems in the past using 1st x'day when the that day falls on the first day of the month. I think the solution was to use '1 sunday september' but it was a long time ago. Hope some of that helps
  14. Think you're talking about tag clouds - Google used to offer an API to create and embed them but I can't find it anymore? A quick search will find a series of jQuery plugins that will take the pain out of creating them. As a counter Jakob Nielsen (a usability expert) has raised his concerns over their effectiveness in terms of usability so have a think if they're going to be useful for your users. They became somewhat of a web design fad over the past few years.
  15. Use the Firefox version over Chrome's version it's a lot better. Also Safari comes built in (at least on Mac) with javascript debugging -> this has the advantage that it picks up JS errors that FF and Chrome don't but it's not as usable as Firefox's.
  16. Yeah sure you basically just need to place it on the line before you start your session... eg: session_save_path($path); session_start(); That's all there is to it really there are a few other functions you can use to improve the security of your sessions in the manual and in addition http://phpsec.org/ has some great articles on sessions.
  17. The main issue's regarding sessions AFAIK is that on shared servers your session text files get stored in the same directory as every other domain on that server - therefore it's not that difficult to create a script to read the session files. To prevent this you call: session_save_path($path_to_folder); Passing to it a writable directory either stored outside the root directory OR one secured using the correct CHMOD settings. The alternative is to have sessions stored in a database - it's quite code intensive compared to changing the session save path but there's an example in Larry's PHP5 advanced. Database driven sessions have a few other advantages in allowing you to interrogate sessions in ways not really possible with file driven sessions. Equally if a site expands and it becomes necessary to host the sites content across multiple servers then database driven sessions are the only way to allow sessions in this environment.
  18. Yeah that makes sense perfect sense. If you planned on storing these values in the session make sure your sessions are secure... most importantly change the session save path (or consider moving towards database driven sessions). You could also consider salting the passwords when you store them to prevent the same passwords having the same hashes. The thing is these are what I'd call utility tasks - which generally means they don't happen very often and so querying the database is not a major problem.
  19. Can you give us examples of the input that's coming through - get these from calling print_r($_POST);
  20. javascript:document.getElementById('pmradios').style.display='block'; Should that : not be a . ? Have you tried using Firebug to debug the JS?
  21. Just my 2c. but I'd approach it slightly differently. You're creating the dropdown off the array returned from your database so just use the meal ID from the database to assign to the option value like: echo '<option value="' . $row['meal1_id'] . '">' . $row['meal1'] . ' at $' . $row['meal_price1'] . '</option>'; Then server side use the ID returned to re-query the database to get the price. This way if the price calculated meant anything (e.g. allowed someone to order meals) they couldn't alter the price charged. As a side note it also looks like you're storing the price alongside with the currency symbol? If so then I think best practice would be to remove that - storing just the numbers allows you to perform math of them. E.G. All prices increasing 10%, converting to another currency for multi-national site and forcing the correct format are all easier to do.
  22. What are you entering into the zip code field? That regex checks for either exactly any 5 digits or exactly 5 digits followed by a dash and any 4 digits. So if it's not the format e.g. 79546 or 79546-1234 then it will fail. If you're in another country e.g. England and entering a postcode like TF11 8PD then it will fail unless you alter the regex.
  23. As much as I don't see a problem with it - I also see no need to? Why not just query the database at the point the user logs in then set a variable to confirm logged in status in the session?
×
×
  • Create New...