Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/16/2023 in all areas

  1. So just to say it, the on event handler is accepting a callback function to run when there is a "play" event. A simpler solution would be to just have a function defined there, that the callback would run, or to define a function globally and pass the name of the function. However, @Kicken coded this function to return an anonymous function. It helps to focus in on return statements in code like this. If you notice the requestSent variable is declared outside the function declaration that does the work. This creates a "closure" (or takes advantage of javascript closure) depending on how you want to think about it. It makes the variable requestSent available to the inner function that is being returned, and this variable will continue to exist in the browser's memory associated with the window/page, until such a time as a new request is made that causes new html/javascript/css to be loaded. An alternative would be to declare requestSent globally and use that, but he gave you something more sophisticated -- a function that returns a function and takes advantage of a variable that is only visible to the anonymous function, and yet is available to the anonymous function across executions. Each time the callback is run, this could be either for the same song or a different song, so inside the function, there is a jQuery call to find the id of the button. let a_id = $(this).attr("id") It's good to think about why this is declared inside the function and how that works. Since this handler can be called for any song, the $(this) resolves in this situation as the song that is being played. Thus the a_id gets set each time there's a play event, and then gets the html id attribute. I added code to push the value onto the requestSent array, which again, since it's part of the closure for the anonymous function, survives across plays. I used Array.includes() to check if the song id already exists in requestSent. If not, I update requestSent with requestSent.push(a_id) and the ajax runs, passing a_id. The ajax is also being done using the jQuery library. The final question you should probably be asking is: if this is a function that returns a function, then how is it, that the callback, which requires a function to run, gets the actual function it needs. A function that returns a function is not a callback. The answer is that again Kicken used an IFFE here. What is actually being passed is a function that is immediately executed. You can see this because after the function definition function () { ... } It is immediately followed by the parens ie. () which causes javascript to execute the function. function () { ... }() So this code works because the function that returns a function, is run immediately, giving the callback parameter what it wants ... a function to run when a play event occurs. The function is anonymous and only bound to the event handler for play events, which also keeps global scope from being cluttered with a symbol table entry for a function that is only needed for the callback. The benefit of doing it this way is that he did not need to utilize a global variable, since closure takes care of this for you. This type of code is favored in many situations, since you don't have a slew of global variables floating around. Nothing outside the callback function can see or modify the requestSent array -- yet it is essentially a private environment that the callback uses. As I said previously -- advanced javascript stuff, that can be confusing if you are still learning javascript. Hope this helps -- using those terms (IFFE, javascript closure, js anonymous function, js callbacks, js this) will lead you to an enormous amount of additional material if you need to explore them further.
    1 point
  2. Another problem with mysqli is that it was obviously written by 2 teams of developers who never spoke to one other. Executing a query produces a result object. Executing a prepared statement produces a statement object. The methods these classes to use to process the outputs are completely different. With PDO, the class methods used are the same for both, making life much easier,
    1 point
  3. FYI - ROLLUP is certainly available in version 5.7 mysql> SELECT VERSION(); +------------+ | VERSION() | +------------+ | 5.7.36-log | +------------+ mysql> SELECT classid as class -> , COUNT(*) as students -> FROM student_class -> WHERE semesterid = 12 -> GROUP BY classid WITH ROLLUP; +-------+----------+ | class | students | +-------+----------+ | 1 | 17 | | 2 | 18 | | 3 | 20 | | 4 | 23 | | 5 | 22 | | 6 | 27 | | 7 | 24 | | 8 | 20 | | 9 | 21 | | 10 | 27 | | 11 | 25 | | 13 | 5 | | 14 | 5 | | 16 | 3 | | 17 | 5 | | 19 | 17 | | NULL | 279 | <--- ROLLUP total +-------+----------+
    1 point
  4. true prepared queries, regardless of the database extension, are equally safe, since they separate the parsing of the sql query syntax from the evaluation of the data. PDO has emulated prepared queries, that should be avoided whenever possible, since, if you haven't set the character set that php is using to match your database tables, which is rarely shown in connection code examples, it is possible for sql special characters in a value to break the sql query syntax, which is how sql injection is accomplished. the PDO examples you have seen that look messier, are probably using named place-holders. PDO also has positional ? place-holders, just like the mysqli extension, which makes converting from using the mysqli extension to PDO straight forward, since the sql query syntax using ? place-holders is exactly the same. to convert to using the PDO extension, you would eliminate the existing msyqli bind_param() call, and supply the array of input data to the ->execute() call. because you can directly fetch data from a PDO prepared query, exactly the same as for a non-prepared query, you don't need to deal with mysqli's bind_result() or get_result() (which is not portable between systems that use and don't use the msyqlnd driver.) another issue with the mysqli extension is that the procedural and OOP notation have different php error responses (though php finally made the mysqli connection always throw an exception upon an error.) things which are fatal problems, that produce fatal php errors when using OOP notation, only produce warnings when using mysqli procedural notation, and allow code to continue to run, producing follow-on errors. an advantage of learning the PDO extension, is that the same php statements work with 12 different database types, so, if you ever need to use a different database type, you don't need to learn a completely new set of php statements for each one.
    1 point
  5. I agree with kicken, but at least with MySQL there are some group by modifiers you can use with your GROUP BY queries, one of which is 'WITH ROLLUP'. With Rollup will produce additional summary value rows for each subgrouping. Of course to use this you need to understand how to identify these rollup rows when you fetch them. Since you only have one GROUP by in your case, there would be one final row with the total count, which you could take advantage of if you wanted to, as an alternative to using a PHP variable. Again, incrementing a variable in a fetch loop is a tried and true solution, but knowing about the group by modifiers is one more tool in your toolbox, which never hurts. You do need a fairly recent version of MySQL ( >= 8.0.12) to use WITH ROLLUP along with a group ORDER BY as you have in your code.
    1 point
  6. Just sum the results as you read them and generate your table. $total = 0; while($fetch=mysqli_fetch_array($query)){ $total += $fetch['total']; //... } //Display your final row with $total as the sum.
    1 point
  7. This is just the code that shows the form. You'd also have to deal with the code that handles the (merged) form - to make sure it understands the new fields that are being included. There's also the possibility the merged HTML isn't correct, so you should also post what you came up with for that.
    1 point
This leaderboard is set to New York/GMT-05:00
×
×
  • 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.