Jump to content

kicken

Gurus
  • Posts

    4,695
  • Joined

  • Last visited

  • Days Won

    177

Everything posted by kicken

  1. They can be NULL in that case because of the LEFT JOIN. The join condition includes p2.submit_time > p1.submit_time, that means for each row in p1 it will attempt to find a row in p2 where p2's submit_time is greater than p1's submit_time (in addition to the other conditions). If it can't find any row that matches, the all the p2 columns will be null. So, since whatever the most recent entry in p1 is won't be able to find a matching row in p2, p2.id will be null and filtering on that condition in the where clause results in you only receiving the most recent rows from p1.
  2. The documentation shows that there is an open method for the date picker, so just add a click handler for your icon that will call that open method. <i class="material-icons prefix datepicker-trigger">calendar_today</i> <input type="text" name="r_date" class="datepicker"> $('.datepicker').datepicker({format: 'yyyy-mm-dd'}); $('.datepicker-trigger').click(function(){ $(this).next('.datepicker').datepicker('open'); });
  3. Just adding it to the prototype means every instance of the object will share the same instance of the function. Given code like this: function Employee(foo) { this.foo = foo; this.name = ''; this.dept = 'general'; } Employee.prototype.method1 = function(){ console.log('Method1 called'); }; function SalesPerson(foo, bar) { Employee.call(this, foo); this.bar = bar; this.dept = 'sales'; this.quota = 100; } SalesPerson.prototype = Object.create(Employee.prototype); SalesPerson.prototype.constructor = SalesPerson; SalesPerson.prototype.method2=function() { console.log('Method 2 called'); } When you this: var p = new SalesPerson(); p.method1(); Javascript looks up method1 by roughly doing: Does p have a property named method1? => No Does SalesPerson.prototype have a property named method1? => No Does SalesPerson.prototype.prototype (Which is Employee.prototype) have a property named method1? => Yes Execute SalesPerson.prototype.prototype.method1.call(p); So only one instance of the method1 function exists on the Employee.prototype object, it's just reused for the other objects. You can see this kind of chain if you console.log(p): If you want to share a single function across multiple objects that are not related via their prototype chain, then you'd do define your function elsewhere and assign a reference to it to each object. This kind of setup is often called a mixin. For example if you had some logging code you wanted to include in each class. var LoggerInterface = { log: function(msg){ console.log(msg); } }; function Employee(foo) { this.foo = foo; this.name = ''; this.dept = 'general'; } Object.assign(Employee.prototype, LoggerInterface); Employee.prototype.method1 = function(){ this.log('Method1 called'); }; function Equipment(){ this.name = ''; } Object.assign(Equipment.prototype, LoggerInterface); Equipment.prototype.method2 = function(){ this.log('Method2 called'); } Both Employee and Equipment would have their own independent .log properties, but they would both reference the same underlying function so the function itself isn't duplicated.
  4. One reason people would define methods in the constructor rather than on the prototype is to simulate private properties. In Javascript all properties are public so anything you attach to an object could be manipulated by other code. To work around that people would keep these "private properties" as regular variables inside the constructor rather than as actual properties on the object. In order to do that and still access them from the methods, the methods need to be defined in the constructor so they can access the constructors variable scope. function Counter(){ var count = 0; this.increment = function(){ count++; }; this.decrement = function(){ count--; }; this.current = function(){ return count; }; } As mentioned, one downside to this is that each instance of the object ends up with it's own instance of the function rather than a single instance being shared. On modern desktops with lots of memory that's probably not an issue unless your creating many thousands of instances of the object. However on older systems or mobile systems with less memory it can cause issues much faster.
  5. The rationale is that even though they are deprecated, they are technically still available to be used and someone may want/need to use them. I've used various libraries in the past that have created a new API and deprecated their old one. Usually updating to the new API isn't something that can be done right away so when I need to work on that code I'll need to continue to use those deprecated functions for a while. Not sure about VSCode but PHPStorm shows such functions with a strike-out in the autocomplete popup as well so you know right away that the function is deprecated. That lets you easily avoid them in new code but still have access to them when maintaining existing code.
  6. Defining a value in the parameter list makes that parameter optional. If it's not provided when the function is called, the it takes on the value assigned to it. Your specific example doesn't really make use of the feature effectively. Take something like this for example though: function findFiles($directory, $includeHidden = false){ $iter = new DirectoryIterator($directory); $list = []; foreach ($iter as $item){ if ($item->isFile()){ $isHidden = $item->getFilename()[0] === '.'; if ($includeHidden || !$isHidden){ $list[] = $item->getPathname(); } } } return $list; } That function requires at least one parameter when it's called, the directory to search. So you end up with the following options for calling it $files = findFiles('/home/kicken'); /* executes with $directory = '/home/kicken', $includeHidden = false */ $files = findFiles('/home/aoeex', true); /* executes with $directory = '/home/aoeex', $includeHidden = true */
  7. Because you aliased it from grade to pgrade.
  8. You need to select the columns in your inner query. Alias them if needed. Then in the outer query is where you use them. mostRecent is the name assigned to the results of the inner query so it is only valid in the outer query and you use it to reference whichever columns you select.
  9. You need have whatever columns you want to order by in the outer query as part of the select clause of the inner query. If you check my original query you'll see I added the grade and nameLast columns to the select list. If you alias them, then use the alias in the order by clause of the outer query.
  10. And I told you: The aliases are only for your SELECT and the outer query. Continue using the table.column name syntax in your conditions and joins.
  11. Yes, that's the point. It loops endlessly as a service checking for work to do. When it finds some, it does it. Otherwise it just sleeps, checking each second for new work. You can adjust the sleep period based on what your requirements are, or implement some method so it sleeps until specifically triggered to check for work (ie, through a socket).
  12. The code I posted needs to have aliases added to it as you discovered. If after adding those you're still having issues then you need to post the code you are using after you've applied your modifications.
  13. Is there a reason you're running it as a separate task in the first place? Most of the time this is done because the work can be time consuming and you don't want the user to have to wait and trying to accomplish that with on-demand task launching can be problematic in PHP in my experience. The best way to accomplish that kind of separation is to simply keep the scripts separate entirely using either a scheduled task or service for one half. There's generally nothing wrong with setting up a job to just run every minute (or whatever you require) to check for work. If there is some, do it. If there isn't, exit. It might feel wasteful to run a script over and over with nothing to do but it's really not an issue and doesn't need to be avoided. The downside to a scheduled task is you can only run it once a minute, if you need faster response times than a minute then you move to a service and either check for work more frequently or communicate with the service via a socket or a job server/queue server (gearman, redis, beanstalked, memcached, etc). For example, I have an application that allows admins to import user accounts from LDAP. The process can take a bit for large imports so similar to you I just INSERT a record into an ldap_import_request table from my web app. On the server I use nssm to run a PHP script as a service and that script essentially runs a loop looking for new records. while (true){ $pendingRequests = loadPendingImportRequests(); foreach ($pendingRequests as $request){ processImportRequest($request); } sleep(1); //Avoid eating up CPU when idle. } You can get more advanced if you want, but I find this simple loop/table setup is fairly effective.
  14. Dont launch your second script from the first. Set it up as a system service (using nssm) or as a scheduled task.
  15. You only use the aliases in the SELECT clause, not your joins or where clauses. Continue to use p.id in those areas, but alias it in the select using p.id as pid Since it's a sub-query each column in the SELECT has to have a unique name so alias any duplicates to something unique. Then in your outer query you use the aliases instead of the original name.
  16. You'll want to do a sub-query to get the most recent 15 in order by the ID, then sort the results of that sub query how you want. SELECT * FROM ( SELECT p.id , b.playerID , b.id , s.toggle AS stoggle , o.toggle AS otoggle , p.city , p.school , s.city , s.school , r.opp_city , r.opp_school , o.city , o.school , r.city , r.school , p.grade , p.nameLast FROM a_players_reviews r INNER JOIN a_players p ON CONCAT (r.nameFirst,r.nameLast) = CONCAT (p.nameFirst,p.nameLast) INNER JOIN a_player_bookmark b ON p.id = b.playerID AND '". $userID ."' = b.userID LEFT JOIN a_schools s ON CONCAT(r.city,r.school) = CONCAT(s.city,s.school) LEFT JOIN a_schools o ON CONCAT(r.opp_city,r.opp_school) = CONCAT(o.city,o.school) WHERE b.bookmark > 0 ORDER BY r.id desc LIMIT 15 ) mostRecent ORDER BY mostRecent.grade , mostRecent.nameLast Some additional notes, if you're going to create a WHERE condition using columns from a joined table, you probably want to use INNER JOIN rather than LEFT JOIN unless you're accounting for NULL values. In general you should use INNER JOIN always unless you have specific reason to use a LEFT JOIN. Your p.id = b.playerID and '$userID' = b.userID conditions are duplicated between your join and WHERE clauses, you only need them in one place, and that is the ON clause so remove them from the WHERE. You didn't qualify your bookmark column with a table but I'm assuming it probably belongs to the a_player_bookmark table (if that's wrong this advice may not apply). If that's the case then your b.bookmark > 0 condition effectively means you're INNER JOINing that table since any null values would fail. As such you can just convert that join to INNER JOIN. If you're intentionally looking for players without a bookmark entry (where the join fails) then you need to make that condition part of the ON clause and use a LEFT JOIN.
  17. How do you determine the most recent entries from a_players_reviews? Is there a datetime column to sort by? Do you want just the most recent row for each player, or the most recent 15 even if multiple of them are from the same player? Sample data and desired output would go a long way to describing what you want.
  18. What platform and PHP version are you using? Can you create some minimal example code that can recreate the crash? I tried setting up some code in a way similar to what you suggest (though I'm not sure what exactly you might be doing and may have got it wrong) and had no issues on windows 10/php 7.3.16
  19. Sounds like all you really need is a class on the parent row's <tr> tag that you can target to apply your padding. That is relatively easy to do by just querying for the .ht_nestingParent cells, getting their parent and adding a class. jQuery(function($){ $('.ht_nestingParent').each(function(){ $(this).parent().addClass('nestingParentRow'); }); }); The you could apply padding to the cells of that row to space it out from the previous section with a little CSS .nestingParentRow td { padding-top: 15px; } .nestingParentRow:first-child td { padding-top: 0; }
  20. Use the -s option: mysql -u $user -p -D $db -Nse "select blah"
  21. You need to use parameter binding rather than variable interpolation.
  22. Your query only returns one row, so there is no need for a loop. Just attempt to fetch that one row and see if any results come back. If so, check them. If not, use your default. $results = mysqli_query($con,$query); $row = mysqli_fetch_assoc($results); if ($row && $row['bookmark']){ echo '-'; } else { echo '+'; }
  23. There's two parts to this, so solve one then the other rather than doing both at the same time. First problem is saving your data. Create a function that you can call with your data and it will save it to your database. Use parameters for the function rather than accessing $_POST directly. For example: function bookmark_add($userId, $itemId){ //run INSERT statement } While getting that working, just use a normal form that will submit the data and refresh the page, eg: <?php if ($_SERVER['REQUEST_METHOD']==='POST'){ //Call your function with the data bookmark_add($_POST['userId'], $_POST['itemId']); } ?> <form method="page.php" action=""> <p>ItemID: <input type="text" name="itemId"></p> <p>UserID: <input type="text" name="userId"></p> <p><button type="submit">Save</button></p> </form> Once you have your function working exactly how you want it, then move on to your "without reloading the page problem." To do this without reloading the page, you need to use javascript to submit the values in the background using AJAX/XHR. Grab something like jQuery and use it's .post method to make this super simple. Now you create a javascript function which will gather your form data and submit it to a PHP page which then calls your PHP function to save it. For example: function submitBookmark(){ var postData = { userId: $('#userId').val() , //.... }; $.post('page.php', postData) .then(/* Success handler */) .catch(/* Failure handler */) ; } Finally setup that function to be executed whenever the user clicks your + image.
  24. You don't really need to check the previous row at all, just create a structured array with the job id as the first key and your columns/children as subkeys. $results = []; while($row = $stmt->fetch(PDO::FETCH_BOUND)) { $jobRow = &$results[$job_number]; if (!$jobRow){ //Job hasn't been seen yet so setup the first level. $jobRow = array( 'Job Number' => $job_number, 'LN #' => null, 'Description' => null, 'Qty' => null, 'AS400 Ship Date' => null, 'Date Showed on Report' => null, 'Days to Manufacture' => null, 'Notes' => null, 'Date Shown Completed' => null, 'Actual Ship Date' => null, 'Qty Shipped' => null, '__children' => [] ); } //Add child line items to the children array $jobRow['__children'][] = array( 'LN #' => $line_item, 'Description' => $description, 'Qty' => $qty, 'AS400 Ship Date' => $as400_ship_date, 'Date Showed on Report' => $date_showed_on_report, 'Days to Manufacture' => "5", 'Notes' => $notes, 'Date Shown Completed' => $date_shown_complete, 'Actual Ship Date' => $actual_ship_date, 'Qty Shipped' => $qty_shipped ); } //Output json. array_values to convert from an object map to an array. echo json_encode(array_values($results));
×
×
  • 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.