Jump to content
Larry Ullman's Book Forums


  • Posts

  • Joined

  • Last visited

  • Days Won


zanimation last won the day on February 14 2012

zanimation had the most liked content!

zanimation's Achievements


Newbie (1/14)



  1. Hi Larry, I am actually using PDO, but was having trouble as to where to actually put/call the connection object in my classes. Now I think I have a better idea on what to do, I've got to factor out reading/writing into separate classes (I also want to support XML format, with possibilities for more formats down the road). If I can get a working application up, I might post it for CC.
  2. Hey Edward, I'm kind of in the same situation as you are, trying to get a grip on how to implement OOP in a web context. I'm trying to build a quizzing application using OOP but already having a tough time on where to put the database functionality, so I'm going to attempt to write factory classes. I've just finished viewing the first lecture video in an open Harvard software engineering course, and it looks promising as a supplementary material. Even though it's titled 'mobile' software engineering, they will be going over web development, MVC, frameworks, and all of that. Have a look. http://cs164.tv/2012/spring/ There's only three videos up at the moment because the course is happening this semester, but as it progresses, more videos will be uploaded.
  3. Ok, It turns out that only one underlying table in a view gets affected when performing inserts / updates. To get around this, I tried writing a trigger for the view which auto-inserts into the subtype table, but it also turns out MySQL doesn't support triggers on views. So not sure... I think my only choice would be to use the first possible method I described, which does 2 separate queries. Even though it's a seemingly clunky solution, I think it's not so bad considering they're contained within a transaction.
  4. I have a MySQL database model where I have different types of users, each having common field names, like 'username', 'password', 'first_name', 'last_name', etc. etc. I've designed it so that these common fields are stored in a 'base' table called 'users' and specific fields that apply to each type of user are stored in derived 'sub-tables' for each type of user. Here is what it looks like: I know that this is a better design than having the 'common' fields stored in every 'user' table. The problem I'm having is I'm trying to figure out how I'm going insert a new user. What would be the best way to handle this? Initially, I'm thinking I could do an insert like this (let's say I wanted to insert a student): <?php // Begin Transaction // Insert the common data into the 'users' table // Get the last inserted ID // Insert the student-specific data into the 'students' table along with the last inserted ID // Commit // If problem occured // Rollback ?> But that just seems like a very crappy way to do it. I would like to have it done in one swift statement. So I haven't had much luck finding clear solutions online, but I recall one person mentioning the use of updatable views for each subtype, where the view would perform an inner join on the subtype table and the base table, and you could insert and update using the single view. I have tried to create a view but keep getting the error: #1356 - View '[view name]' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them. Where [view name] is the name of my view. I get this error even when just selecting one column from one table and I know the names are right. Would the 'view' approach be the best way to go, assuming I can figure out how to get it to work? Is there a better way than what I've mentioned so far? Much thanks, Zane EDIT: Oh, and the PK 'user_id' is an auto-incremented INT in the users table. EDIT 2: Got my view to work. Turns out I had to specify the SQL SECURITY line as INVOKER instead of the default DEFINER. Going to try to see if I can perform inserts and updates on this view...
  5. Hmm... I haven't read the book, but it seems like what the script was trying to do was to ensure that the user knows the current password in order to enter in a new password, otherwise he/she cannot enter a new password. By removing the second part of the AND clause, you are completely bypassing that validation, so you'll definitely want to leave it in. Instead, let's try to figure out why SHA1 did not work. There are a few reasons why it's not working: Check that the column name 'pass' is consistent in the script and in the database If column names are consistent, check if the password is encrypted If encrypted, check that the SHA1 encrypted value for 'test' is the same in the database You can check if the encrypted values are the same by inserting this temporary line after $cp='test'; echo sha1($cp); Then compare the encrypted string with what's in the database. If it's not the same, then something went wrong with inserting the original password.
  6. Hmm... Not sure if I see anything right away that would cause it not to select. Try this: Right after you echo 'step3', put this: echo mysqli_errno($dbc) . '<br />'; echo mysqli_error($dbc); It will return a mysqli error code and string which should provide more information.
  7. The quotes for your query seem all messed up and mismatched. You also don't need to concatenate anything. Here it is fixed: $query = "INSERT INTO poem_orders (firstname, lastname, email, selectpoemtype, keynames, specificwords, poemisfor, relationship, occasion, overallmessage, anythingelse) VALUES ('$first_name', '$last_name', '$email', '$select_poem_type' '$key_names', '$specific_words', '$poem_is_for', '$relationship', '$occasion', '$over_all_message', '$anything_else')"; It seems you are also not executing your query. You are defining your query, but I see nothing that executes it. I'm not familiar with mysqli as I mainly use PDO, but try adding this just after your query definition: $success = mysqli_query($dbc, $query); // if query was successful, display message to user: if($success) { echo 'Thank you, ' . $firstname . $lastname; echo 'Thanks for submitting the form.<br />'; echo ' Poem Type: ' . $selectpoemtype; echo ' Key names to include: ' . $keynames . '<br />'; echo 'Specific Words To Include: '. $specificwords . '<br />'; echo 'Poem is for: ' . $poemisfor . '<br />'; echo 'Relationship: ' . $relationship . '<br />'; echo 'Occasion: ' . $occasion . '<br />'; echo 'Overall Message: ' . $overallmessage . '<br />'; echo 'You also added: ' . $anything_else; } else { echo 'Error: Query failed.'; } Also note that your query is wide open to SQL injection. While it's best to use prepared statements, you can just do this to prevent SQL injection: $email = "myemail@gmail.com"; // Email to notify on error $first_name = mysqli_real_escape_string($_POST['firstname']); $last_name = mysqli_real_escape_string($_POST['lastname']); $email = mysqli_real_escape_string($_POST['email']); $select_poem_type = mysqli_real_escape_string($_POST['selectpoemtype']); $key_names = mysqli_real_escape_string($_POST['keynames']); $specific_words = mysqli_real_escape_string($_POST['specificwords']); $poem_is_for = mysqli_real_escape_string($_POST['poemisfor']); $relationship = mysqli_real_escape_string($_POST['relationship']); $occasion = mysqli_real_escape_string($_POST['occasion']); $over_all_message = mysqli_real_escape_string($_POST['overallmessage']); $anything_else = mysqli_real_escape_string($_POST['anythingelse']); http://www.php.net/manual/en/mysqli.real-escape-string.php Zane
  8. $dbc = mysqli_connect('localhost', 'login', 'password', 'database'); " . or die('Error connecting to MySQL server.'); It seems you've left the ;" . after mysqli_connect() which is causing your whole sql definition to mess up. Take out the semicolon, quotation, and the period and see if it works: $dbc = mysqli_connect('localhost', 'login', 'password', 'database') or die('Error connecting to MySQL server.');
  9. The question is very vague. I think Larry covers it in his book. If anything, just Google something like 'php login using prepared statements'. Here's basically how I use prepared statements to handle logins (simplified and using the PDO interface): <?php // include connection functions (houses the 'dbConnect()' function) require_once(PATH_TO_INCLUDES_FOLDER . 'connection_inc.php'); if(isset($_POST['login'])) { // connect to database on the read-only account and create a PDO connection object $conn = dbConnect('read'); // define the sql statement with two input parameters: username and password $sql = 'SELECT username, password FROM users WHERE username = :username AND password = :password'; // prepare sql statement into a statement object $stmt = $conn->prepare($sql); // encrypt password and store in a temporary variable $enc_pwd = sha1($_POST['password']); // bind parameters with user-input $stmt->bindParam(':username', $_POST['username'], PDO::PARAM_STR); $stmt->bindParam(':password', $enc_pwd, PDO::PARAM_STR); // execute prepared query $stmt->execute(); // if there was a row selected (username and password match found in the database) if($stmt->rowCount()) { // log in user and do whatever else you need to do on login success } // otherwise if a row wasn't selectd (no username/password match found in the database) elseif(!$stmt->rowCount()) { // display error message and do whatever else you need to do on login failure } } ?> If you're just looking for someone to spit out code that you can simply copy and paste, the code above won't work, it's just showing one way to structure your code for using prepared statements in login verification. In order to answer your question better, you should provide information like: What interface you're using to connect to your database (PDO? mysqli? mysql?, etc) Are you encrypting your passwords? Do you use salts with your encryption? What do you want to happen when the user logs in successfully? What about when they don't log in successfully? We're not going to write out the entire code for you(unless someone's really generous) but we'll help you out where you're having trouble with something. Please be specific! Zane
  10. Since != is a comparison operator(not an assignment operator), you'll want to change: $emphasise != $emphasise; to $emphasise = !$emphasise; Also, here's an alternate modified version of Stuart's code which avoids the need for conditional checks and an extra variable: $string = 'the quick brown fox jumps over the lazy dog'; $words = explode(' ', $string); for($i = 1; $i < count($words); $i += 2) { $words[$i] = '<strong>' . $words[$i] . '</strong>'; } echo implode(' ', $words); If you're going to be using it frequently throughout your code, here's a functionalized form: function emphAltern($string, $start = 1) { $words = explode(' ', $string); for($i = $start; $i < count($words); $i += 2) { $words[$i] = '<strong>' . $words[$i] . '</strong>'; } return implode(' ', $words); }
  11. The example script in the book includes the header on the bottom line but it's just a mistake... you'll need to change it to <?php include('templates/footer.html'); ?> (it makes more sense).
  12. Looking at the PHP manual for the mysqli functions: http://us.php.net/manual/en/mysqli.query.php and http://us.php.net/manual/en/mysqli.select-db.php Try reversing the position of the function arguments: $dbc and 'string' e.g. mysqli_select_db($dbc, 'myblog') mysqli_query($dbc, 'CREATE DATABASE myblog') See if that works. Zane
  13. While practicing some of the 'pursue' instructions for ch. 9(p. 256), I think there's an error: Rewrite customize.php so that the script also applies the user's preferences. Hint: You need to take into account the fact that the cookies aren't available immediately after they've been set. Instead, you would write the CSS code using the $_GET values after the form has been submitted, the $_COOKIE values upon first arriving at the page (if the cookies exit), and the default values otherwise. I believe it's supposed to be $_POST, not $_GET. And btw, I'm thoroughly enjoying your book... planning to buy more.
  • Create New...