- This topic is empty.
-
AuthorPosts
-
May 30, 2014 at 1:18 am #171423chrisburtonParticipant
Is this what you’re trying to relay to me about using functions?:
May 30, 2014 at 10:22 am #171451__ParticipantYeah, kinda. His example misses a big point, however. It’s more than moving everything into a function definition; it’s about making the code more flexible and usable is more situations. In his example, the function makes a nav bar and prints it. This means that you can’t use the function unless you actually want to print the nav bar, too. If you wanted to get the nav bar HTML without printing it, then you’d have to create a whole second function that duplicates most of that code. (There’s also the issue of this being no better for error handling than the original code, but we’ll set that aside for now.)
Here’s the basic PHP function syntax:
function
keyword- function label (name)
- opening paren
- argument list
- closing paren
- opening curly brace
- function body (i.e., the code)
- closing curly brace
So, you have:
function name_of_function( $arg1,$arg2 ){ /* code goes here */ /* <code>return</code> statement goes here */ }
Arguments are optional. Most functions have args, but some don’t need any. You define arguments by putting varibale names inside the parens, as above. You can give arguments default values to make them optional:
$arg2="default value"
.return
statements are also optional. If you don’t have one, the function returns “void” (i.e., nothing) when it’s done. As a general rule, most functions you write should have return values. Also as a general rule, “side effects” (things done inside a function that also change things outside the function, e.g., printing the html for a nav bar) should not happen.Rewriting the function in that vid:
<?php function nav_main( $dbc, $pageId ){ $q = "select <code>id</code>,<code>label</code> from <code>pages</code>"; $r = mysqli_query( $dbc,$q ); $html = '<ul class="nav navbar-nav">'; while( $nav = mysqli_fetch_assoc( $r ) ){ $html .= ($nav['id'] === $pageId)? '<li class="active"><a href="'.$nav['id'].'">'.$nav['label'].'</a></li>': '<li><a href="'.$nav['id'].'">'.$nav['label'].'</a></li>'; } $html .= '</ul>'; return $html; }
Instead of printing the HTML as it is generated, it is collected in the
$html
variable. Then, when we are done, wereturn
that variable. Instead of having uncontrollable side effects, you simply get a string back from the function:$nav_html = nav_main( $dbc,$pageId );
…which you can print, use to do other things, whatever.
May 30, 2014 at 11:14 pm #171478__ParticipantSo, let’s start with your page, and break down what it does. It:
- checks for form submissions and redirects them to avoid duplicate submissions
- inserts new records
- reads existing records
- displays existing records in a table for editing
- shows a form for creating new records.
We’ll write functions that do each of those things.
redirect_POST
client_insert
client_select
client_table
client_insert_form
Then, we’ll make one more function for templating. When you make an ajax request, HTML output will ruin the JSON response, so you don’t want your php page to have any output by default.
client_page_HTMLtemplate
With all the work being done inside of functions, your script becomes a “controller.” It’s much cleaner and easier to see what’s going on:
<?php session_start(); // check for form submission & do session redirect if necessary redirect_POST(); // prepare the database connection $DB = new mysqli( 'host','username','password','dbname' ); // if a new record was submitted, insert it if( $_POST ){ client_insert( $DB,$_POST ); } // select client records from db $records = client_select( $DB ); // display records in a <table> $table = client_table( $records ); // display table and new record <form> in html page template print client_page_HTMLtemplate( $table.client_insert_form() ); // all done exit;
Here’s a gist with everything.
June 2, 2014 at 12:32 pm #171601chrisburtonParticipant@traq Hey, sorry for not responding! I’ve been quite busy lately. Thank you so much for helping me on this. I’ll take a look as soon as I can.
Thanks again.
June 2, 2014 at 3:44 pm #171602__Participantno prob.
June 5, 2014 at 6:29 am #171917chrisburtonParticipantJune 5, 2014 at 9:45 am #171948__ParticipantCall to a member function fetch_all() on a non-object
Meaning
$result
is not an object.$result
came from$result = $db->query( $sql )
.mysqli::query
returns an object on success andfalse
on failure, so we can assume that$result
isfalse
.Normally, we would check if the query succeeded before trying to read the results. But since you’re using try…catch blocks, we should have them catch the errors for us—that’s the whole point, right? : )
Errors in PHP, unfortunately, are not the same as Exceptions. You can make them the same, though, using the
ErrorException
class.<?php set_error_handler( function( $errno,$errstr,$errfile,$errline ){ throw new ErrorException( $errstr,0,$errno,$errfile,$errline ); } );
This will take every PHP error, turn it into an Exception, and throw it. That way, your
catch
blocks can catch them with no extra effort.Put this at the beginning of your script (or,
require_once
it in the class definition file).Then, let’s add some debugging stuff to the
catch
block:// . . . catch( Exception $e ){ print "{$db->error}<br>$sql"; return false; }
This will show us MySQL’s error message, and the SQL statement we built.
June 8, 2014 at 2:10 pm #172189chrisburtonParticipantFirst, I really apologize for disappearing. I’ve been helping people with an unexpected renovation and it has been hell.
Anyway, I ended up having to manipulate your code a bit to get it to work. The only thing I believe is missing is the update function so that I am able to call it via jQuery on
.blur()
.I’ll let you know as soon as I can get back to what we started without interruptions.
June 8, 2014 at 5:24 pm #172192__ParticipantWell, what I’ve written so far basically only abstracts it from your original code. You would need to add a way to check if the form (POST) submission is coming from your “new record” form, or is an update. You’d also need to know if it’s a regular page request or via ajax (so you know whether to respond with HTML or JSON).
Don’t worry about disappearing. It happens, and I’m in no hurry.
June 10, 2014 at 11:45 am #172311chrisburtonParticipant@traq I’m a little confused. Why would I check if the submission is coming from my form? At this point, wouldn’t I just need to update the record in my table with the
.blur()
function?For a logic example:
click on textarea and change a value in my HTML table =>
click out of the textarea (.blur()
) =>
update the new value to the database.June 10, 2014 at 12:03 pm #172312__ParticipantWhy would I check if the submission is coming from my form?
Because the form (the actual
<form>
) represents a new record; whereas your table represents records to be updated. If it’s an actual form submission (or the original page request), your response would be a full HTML page, whereas your submissions onblur
need JSON responses.I’ll make some changes to illustrate my meaning.
June 10, 2014 at 2:02 pm #172324chrisburtonParticipantI’ll make some changes to illustrate my meaning.
I appreciate that. I’m still a bit confused.
June 10, 2014 at 4:09 pm #172342__ParticipantBefore I start, note that I completely rewrote the
redirect_POST
function. Now, we give it a variable that we want to be available after the redirect. I also added aclient_update
function, which -you guessed it- updates the database. (I thought I had already written this, but I guess not.) Before trying this, download everything fresh from the gist.Okay:
When a request comes in, we need to decide a few things: First, if there is anything in POST (a database insert or update); second, if so, whether it posted via AJAX (i.e., do we respond with HTML or JSON)?
Here’s the rewritten page controller:
<?php # start session session_start(); # decide on response type. # use POST "ajax=1" to distinguish AJAX requests and send JSON responses; # will default to HTML otherwise. $ajax = isset( $_POST["ajax"] ); # prepare the database connection. $DB = new mysqli( 'host','username','password','dbname' ); # check POST and process any form submission first. # this is a change from our previous approach: we will redirect later if needed. if( $_POST ){ # if an ID exists, this is an update; otherwise, it's a new record. $update = isset( $_POST["id"] ); # process form submission & query DB $success = $update? client_update( $DB,$_POST ): client_insert( $DB,$_POST ); # prepare response data. # you could assign other parts to the response as desired, # for example, you might provided a more helpful message, # or we might return the ID for new inserted records. $response = [ "success" => (int)$success, "message" => ($update? "update": "insert").($success? " successful": " failed") ]; # if this is an ajax request, we send the response as json and stop here. if( $ajax ){ echo json_encode( $response ); exit; } # otherwise, we redirect (the whole browser history workaround). # only difference is, instead of passing POST through the session, # we'll pass the response data. redirect_POST( $response ); exit; } # if we get to this point, it's a normal page request and we send HTML. # get records from DB $records = client_select( $DB ); # look for a "response" from insert/update $response = isset( $_SESSION["redirect_POST_data"] )? "<div class=notice>{$_SESSION["redirect_POST_data"]["message"]}</div>": ""; # the content of the HTML response will have three parts: # - the response from inserting/updating records (if any, in SESSION) # - the records, displayed in a <table> # - the <form> for submitting new records $content = $response .client_table( $records ) .client_insert_form(); # display content as HTML print client_page_HTMLtemplate( $content ); exit;
The javascript that will allow you to update the records displayed in the table is what we need to write next.
-
AuthorPosts
- The forum ‘Back End’ is closed to new topics and replies.