Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 09/23/2012 in all areas

  1. Too many people are obsessed with "filtering" bad inputs. You don't have to "filter" anything. You don't have to remove HTML tags. You don't have to remove SQL keywords. You don't have to strip quotes or backslashes. All you have to do is make sure that whatever the user typed doesn't screw around with what you're trying to do. Want to put it into HTML? Make sure it doesn't screw around with your HTML. Want to put it into SQL? Make sure it doesn't screw around with your SQL. Want to send it in JSON? Make sure it doesn't screw around with your JSON. And every single one of those situations has a simple, single best-practice solution: HTML? Use htmlspecialchars with ENT_QUOTES* and the correct charset. SQL? Use prepared statements. JSON? Use json_encode. That's it. No filter_vars or filter_inputs, no strip_tags, no regular expressions, nothing stupid like that. User wants to look cool and type <script> tags into their forum post? Go ahead and let them, because it'll just show up as plain and simple text. Like it just did now. * Only actually required if you are putting the input into an single quote-delimited tag attribute. Using double quotes for your attributes? Not outputting into an HTML tag? Then you don't technically need ENT_QUOTES.
    3 points
  2. I enjoy the challenge when someone posts a problem I can get my teeth into.
    3 points
  3. People still use StackOverflow? That's only half a joke. Their community has always been toxic to newcomers and there's so much emphasis on correctness that anything less than perfect is unacceptable. And there's the hostility towards any form of discussion about what is right that I always mention when this subject comes up. SO is good when you're looking for a precise answer to a specific question, but it's terrible for actually asking the questions, or trying to weigh in as a new person with different answers. But I am glad they dethroned Expert Sex Change in search results. edit: If Your Common Sense/shrapnelcol came across this thread and decided they wanted to join our forum...
    3 points
  4. A few notes about text bounding boxes which, I hope, will help in precise placement of your text. Suppose I have the text string "The lazy fox" which I want to display using 150pt Vivaldi . My image is 4896 x 3672 and I want the text placed at the bottom right but 250 pixels from the edges of the image. $box = imagettfbbox(150,0,'c:/windows/fonts/vivaldii.ttf','The lazy fox'); gives this array of coordinates of the four corners $box = Array ( [0] => 23 [1] => 55 [2] => 871 [3] => 55 [4] => 871 [5] => -140 [6] => 23 [7] => -140 ) You may wonder why it can't just give a rectangle from (0,0) to (width, height) to make sizing simple, but there is extra information to be extracted from the array Text width = (871 - 23) = 848 Text height = 55 - (-140) = 195 The baseline will be 140px from the top The text is offset 23 px to the right. My text, therefore, will be in a rectangle 848 x 195 positioned 250 px from right and bottom edges. The top left x coord of the rectangle will be (4896 - 250 - 848) = 3798 and top left y coord will be (3672 - 250 - 195) = 3227. However, to land the text precisely into this area we position it on the baseline and at the required x offset, ie (3798 - 23 , 3227 + 140) = (3775, 3367). I use a simple custom function to assist with this process function metrics($font, $fsize, $str) { $box = imagettfbbox($fsize, 0, $font, $str); $ht = abs($box[5] - $box[1]); $wd = abs($box[4] - $box[0]); $base = -$box[5]; $tx = -$box[0]; return [ 'width' => $wd, 'height' => $ht, 'ascent' => $base, 'offsetx' => $tx ]; } $box = metrics ('c:/windows/fonts/vivaldii.ttf', 150, 'The lazy fox'); $box = Array ( [width] => 848 [height] => 195 [ascent] => 140 [offsetx] => -23 )
    3 points
  5. Don't use $GLOBALS. Forget it exists. There is never a good reason to use it. Pretend you never saw it.
    3 points
  6. +----------------+ +----------------+ | Make sure to |---+ +------->| (e.g. Courier) | +----------------+ | | +----------------+ | | | | +----------+ | | +->| use a |---+ | | +----------------+ +----------+ | | +------->| and use spaces | | | +----------------+ | +----------------+ | | +--->| monospace font |-----+ | +----------------+ | +----------+ | | not tabs |<----------+ +----------+ | +--------------------------------------------------------------------------+ | V +---------------+ | It also helps | +---------------+ | | | +-------------------+ +-------------------+ +------------------------>| if you sometimes |---------------------->| switch between | +-------------------+ +-------------------+ | | +-----------------+-----------------+ | | | | +-------------------+ +-------------------+ | overtype | | insert | +-------------------+ +-------------------+ | | | | | +----------+ | +----------=>| modes |<----------+ +----------+
    3 points
  7. The code in each switch is identical so all it achieves is to ensure the calculation uses only the defined list of diameter options. Just use an array of the valid values to verify the values. You can use the same array to generate the option list <?php $diam_vals = [2,3,4,6,8,10,12,14,16,18,20,22,24,26]; $results = ''; if ($_SERVER['REQUEST_METHOD']=='POST') { $x = $_POST['x'] ?? 0; $y = $_POST['y'] ?? 0; $diametre = $_POST['diametre'] ?? 0; if ($x > 0 && $y > 0 && in_array($diametre, $diam_vals)) { $rayon = $diametre * 38.1; $dc = $x/2; $ad = ($y/2)-$rayon; $ac = sqrt(pow($ad,2) + pow($dc,2)); $ec = sqrt(pow($ac,2) - pow($rayon,2)); $LongueurBayonette = $ec*2; $alpha = asin($dc/$ac); $alpha = $alpha*180/M_PI; $beta = acos($rayon/$ac); $beta = $beta*180/M_PI; $angle = 180-$alpha-$beta; $results .= "X = " . $x . "mm" . "<br/>"; $results .= "Y = " . $y . "mm" . "<br/>"; $results .= "Longueur = " . number_format($LongueurBayonette,1) . " mm" . "<br/>"; $results .= "&beta; = " . number_format($angle,1) . "°" . "<br/>"; $results .= "Rayon = " . $rayon . " mm" . "<br/>"; $results .= "&phi; = " . $diametre . '"' . "<br/>"; } else { $results = 'Inputs are not valid'; } } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Simplified Example</title> </head> <body> <form method="post" action=""> <fieldset> X: <input type="text" name="x" value="" /> <br/> Y: <input type="text" name="y" value="" /> <br/> Diametre: <select name="diametre"> <option value="0"> </option> <?php foreach ($diam_vals as $d) { echo "<option value='$d'>$d</option>\n" ; } ?> </select> <input type="submit" value = "Calculer" /> </fieldset> </form> <br> <?=$results?> Just curious - do you have a diagram of how those values relate to one another. It metions "rayon" and "bayonnette" so my guess is that it is some kind of laser rifle with attached bayonet (but I could be wrong) ?
    3 points
  8. I have to agree - do a single query to get the events for the month. I would set up a calendar array of the days in the month (structure: $calendar[wk][wkday][events] ) Loop through the query results and drop the events into their respective week/day slots Loop throught the array to output the calendar DATA TABLE: event +----+----------+---------------------+ | id | name | date_time | +----+----------+---------------------+ | 1 | Event 1 | 2018-11-01 15:00:00 | | 2 | Event 2 | 2018-11-02 12:00:00 | | 3 | Event 3 | 2018-11-11 14:00:00 | | 4 | Event 4 | 2018-11-14 11:00:00 | | 5 | Event 5 | 2018-11-15 14:00:00 | | 6 | Event 6 | 2018-11-16 15:00:00 | | 7 | Event 7 | 2018-11-19 15:00:00 | | 8 | Event 8 | 2018-11-20 16:00:00 | | 9 | Event 9 | 2018-11-23 14:00:00 | | 10 | Event 10 | 2018-11-30 10:00:00 | | 11 | Event 3A | 2018-11-11 16:00:00 | +----+----------+---------------------+ CODE <?php include('db_inc.php'); $db = pdoConnect("test"); // connect to "test" database $curmonth = date('F Y'); // // set up the date range required // $dt1 = new DateTime("first day of this month"); $dt2 = clone $dt1; $dt2->add(new DateInterval('P1M')); $dint = new DateInterval('P1D'); $dper = new DatePeriod($dt1, $dint, $dt2); // // create an array calendar[wk][wkday][events] to store events then output // $calendar = []; foreach ($dper as $d) { $wk = $d->format("W"); $calendar[$wk] = array_fill_keys(range(0,6), []); } // // get the event data for current month // $stmt = $db->query("SELECT id , DATE_FORMAT(date_time, '%D') as day , WEEK(date_time, 1) as wkno , WEEKDAY(date_time) as wkday , DATE_FORMAT(date_time, '%k:%i') as time , name FROM event WHERE YEAR(date_time) = YEAR(CURDATE()) AND MONTH(date_time) = MONTH(CURDATE()) ORDER BY wkno, wkday, time "); // // loop through results and drop events into the array // foreach ($stmt as $ev) { $calendar[$ev['wkno']][$ev['wkday']][] = [ 'day' => $ev['day'], 'time' => $ev['time'], 'name' => $ev['name'] ]; } // // output the array // $tdata = ''; foreach ($calendar as $wk => $wdata) { $tdata .= '<tr>'; foreach ($wdata as $dno => $events) { $cls = $dno > 4 ? "class='we'":""; $tdata .= "<td $cls>"; foreach ($events as $ev) { $tdata .= "{$ev['day']} {$ev['time']} {$ev['name']}<br>"; } $tdata .= "</td>\n"; } $tdata .= "</tr>\n"; } ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="generator" content="PhpED 18.0 (Build 18044, 64bit)"> <meta name="creation-date" content="11/06/2018"> <title>Sample Calendar</title> <style> table { border-collapse: collapse; font-family: verdana, sans-serif; font-size: 10pt; } th { background-color: #369; color: white; padding: 5px; width: 14%; } th.we { background-color: #358; } td { background-color: #FFE; padding: 5px; } td.we { background-color: #FFC; } </style> </head> <body> <h3>Calendar <?=$curmonth?></h3> <table border='1'> <thead> <tr><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th class='we'>Sat</th><th class='we'>Sun</th></tr> </thead> <tbody> <?=$tdata?> </tbody> </table> </body> </html> OUTPUT
    3 points
  9. I can't imagine a scenario where the gobbledy-gook of a system you apparently are trying to create would be justified, or possible within your demonstrated engineering capabilities. You are talking about trying to create a system that requires a user to only use one workstation and browser to access your system. I don't know what your system would be doing, but it better be providing literally life saving services, because short of that, nobody is going to put up with the restrictions you have in mind. They are anti-user, and when you make things difficult for users, they stop using your system, or never even stay long enough to pass the entry point. It is damn difficult to get anyone to sign up to use legitimately valuable services, which is why you see so many systems that integrate with facebook, google and twitter, so that you can create your account and trust authentication from those systems to allow access. Furthermore some of your plans reflect an apparent lack of understanding of Internet basics like NAT. In your system, if we were to follow along with your plans, for a large company with perhaps 1000 employees at a particular site, you plan to only allow 1 employee there to use your system. Ditto universities, or even an average household: "Hey there roommate, I just made an account at this site, you should too!" "WTF, the system says I'm banned!" Since you are focused on investigating a client IP, I will say this about IP addresses -- they are reliable at least to the degree that they reflect the tcp socket connection from the client to the server. That information bubbles up to PHP from the IP layer, to the server, and finally to PHP's $_SERVER superglob. The problem is, that a client could have bounced through a variety of gateways, proxy servers or VPN prior to the point that you are finally connected. In many sophisticated hosting environments there are things like load balancers or reverse proxy servers that sit between the client connection and the server which interfere with $_SERVER['REMOTE_ADDR']. Rather than see the client IP, you instead see the IP of the proxy server. If you have that sort of environment, then you can examine $_SERVER['X-Forwarded-For'] or $_SERVER['HTTP_X_FORWARDED_FOR'] variables. These may be arrays with a series of addresses. Again you have the issue that these are provided by the "client" so if it is a proxy server you can depend on at least the most recent address to have been the one that made the TCP socket connection to YOUR proxy server. Other legitimate proxy servers will provide the same data. However, someone who is taking steps to hide their origin is not going to be prevented from obscuring their IP and there is absolutely nothing you can do about it. Almost everyone uses NAT in some form, so the actual person IP address of a workstation on a network is never going to be visible (and would also be useless if it was, since these will be non-routable IP addresses that are shared by hundreds of millions of users). Solutions to the issue of certification and authentication, when people have real and legitimate reasons to solve them, involve cryptography. What you are trying to do can be accomplished using X.509 certificates which have support built into browsers. In a nutshell, at account creation time you would generate an client certificate for that user, installing that into your server, and then providing the signed cert back to them in a specific header (application/x-x509-user-cert ). This will cause the browser to prompt the user to install the cert into their browser. If they accept you know have a reliable way of identifying a specific user. At that point, whenever they connect (must be under SSL) you'll be able to authenticate them back to your system via that particular certificate. Those without a client certificate will be unable to connect. You can think of this as white listing. It is highly effective but is typically used only in environments where the system knows in advance who their allowed users are. Trying to use it in a public facing website with an unknown user base is something you just don't see because the benefits of trying to do this far outweigh the tolerance that people have for a system that has that degree of odious overhead and invasion of their privacy. In conclusion: The types of things you are obsessed with are all edge case items. No quality system begins with the premise that the #1 goal is to try and catch and outsmart an imaginary horde of people attacking your site for reasons unknown. This started as a specific thread about the contents of $_SERVER variables and then escalated into fairly delusional territory, with a dash of your personal Devshed drama thrown in. And let's just be clear about one thing: If you ever bring up your personal issues regarding your Devshed access again, which are irrelevant to this community, then your access to this community will end as well. It's off topic, it's a waste of people's time and efforts here, and it's rude. I just want to be clear that I won't tolerate it again.
    3 points
  10. Or avoid the concatenation which is usually the biggest source of error (and the query string needs an "=") echo "<a href='icerik.php?icerik={$goster['icerik_id']}'>{$goster['baslik']}</a>";
    2 points
  11. This fails $j = "{'admin': 1, 'moderator': 1}" ; $a = json_decode($j, 1); echo '<pre> a ' . print_r($a, 1) . '</pre>'; This works $j = '{"admin": 1, "moderator": 1}' ; $b = json_decode($j, 1); echo '<pre> b ' . print_r($b, 1) . '</pre>'; Note the quotes in the JSON string.
    2 points
  12. Doesn't your console have a "preserve" option? Or, add "return false" to the end of your submitData() function to stop the page refreshing
    2 points
  13. A more efficient way is to only select the 8 rows you're looking for instead of selecting the entire table.
    2 points
  14. Hello everyone, I'm very new to this site. I'm here to learn how to code in PHP as I once did. I'm very raw at tho, and I'm looking to start back up in it again. So again, hello everyone and remember I'm new. So any dummy questions I made ask, please bear with me. I would like to start my own web site for my own purpose. Something very small and for my needs. And to top it all off, I'm going to run it on a Raspberry Pi from my home. This is should be a fun trip. Thanks Sincerely Dan
    2 points
  15. These are the results I get (wordlist contains 351,100 records) $t1 = microtime(1); $res = $db->query("SELECT word FROM wordlist WHERE MATCH (word) AGAINST ('sang*' IN BOOLEAN MODE)"); $t2 = microtime(1); printf('Query 1 : %0.4f seconds<br>', $t2 - $t1); $t1 = microtime(1); $res = $db->query("SELECT word FROM wordlist WHERE word LIKE 'sang%'"); $t2 = microtime(1); printf('Query 2 : %0.4f seconds<br>', $t2 - $t1); results (74 words found) Query 1 : 0.0026 seconds Query 2 : 0.0005 seconds
    2 points
  16. In case anyone comes here and wants to know what the answer was, since that wasn't shared, Problem 1 - phpunit/phpunit[9.3.3, ..., 9.5.x-dev] require ext-dom * -> it is missing from your system. Install or enable PHP's dom extension. - Root composer.json requires phpunit/phpunit ^9.3.3 -> satisfiable by phpunit/phpunit[9.3.3, ..., 9.5.x-dev]. phpunit requires ext-dom (aka the DOM extension) but apparently it's missing. Install it.
    2 points
  17. less... $matched = array_intersect_key($all, array_flip($referred_by_Affiliate));
    2 points
  18. Here's my attempt DATA mysql> select * from ajoo -> order by user, recno; +-------+----------+---------+---------+ | recno | user | v_score | rollavg | +-------+----------+---------+---------+ | 6 | mina1111 | 4 | 3.2500 | | 7 | mina1111 | 3 | 3.2000 | | 8 | mina1111 | 2 | 3.2000 | | 9 | mina1111 | 4 | 3.4000 | | 10 | mina1111 | 5 | 3.6000 | | 11 | mina1111 | 0 | 2.8000 | | 12 | mina1111 | 1 | 2.5000 | | 13 | mina1111 | 1 | 1.7500 | | 14 | mina1111 | 1 | 0.7500 | | 1 | nina1234 | 3 | NULL | | 4 | nina1234 | 3 | 2.5000 | | 5 | nina1234 | 4 | 3.0000 | | 15 | nina1234 | 5 | NULL | | 17 | nina1234 | 2 | 2.0000 | | 22 | nina1234 | 2 | NULL | +-------+----------+---------+---------+ QUERIES -- -- create temp table a -- CREATE TEMPORARY TABLE temp_a SELECT a.recno , a.v_score , @count := CASE WHEN user = @prevu THEN @count+1 ELSE 1 END AS reccount , @prevu := user AS user FROM ajoo a JOIN (SELECT @count:=0, @prevu:=NULL) AS init ORDER BY user, recno ; -- -- create temp table b -- (copy of temp_a) -- CREATE TEMPORARY TABLE temp_b SELECT * FROM temp_a ; -- -- get results -- SELECT av.user , avg5 , tot3 FROM ( SELECT user , AVG(v_score) as avg5 FROM ( SELECT a.user , v_score FROM temp_a a JOIN ( SELECT user , COUNT(*) AS maxrec FROM ajoo GROUP BY user ) max ON a.user = max.user AND a.reccount > max.maxrec - 5 ) tots GROUP BY user ) av JOIN ( SELECT user , SUM(v_score) as tot3 FROM ( SELECT b.user , v_score FROM temp_b b JOIN ( SELECT user , COUNT(*) AS maxrec FROM ajoo GROUP BY user ) max ON b.user = max.user AND b.reccount > max.maxrec - 3 ) tots GROUP BY user ) tot USING (user) ; RESULTS +----------+--------+------+ | user | avg5 | tot3 | +----------+--------+------+ | mina1111 | 1.6000 | 3 | | nina1234 | 3.2000 | 9 | +----------+--------+------+
    2 points
  19. Don't use "SELECT * ". Specify the columns you want. This makes it easier for others, like me, to understand what is in the table and what the query is doing. Indent your code to show the nested structure of loops etc. If you had done those I might have given this problem more than a cursory glance. So you'll have to settle for a generic example of using a recursive function to give an indented list of parent/child elements. Also, Don't run queries inside loops. Use JOINs to get all the data in a single query THE DATA TABLE: category +----+---------+--------+ | id | name | parent | +----+---------+--------+ | 1 | happy | 0 | | 2 | comet | 0 | | 3 | grumpy | 0 | | 4 | prancer | 1 | | 5 | bashful | 1 | | 6 | dancer | 2 | | 7 | doc | 2 | | 8 | blitzen | 2 | | 9 | dasher | 3 | | 10 | donner | 1 | | 11 | vixen | 1 | | 12 | cupid | 8 | +----+---------+--------+ THE OUTPUT THE CODE <?php $sql = "SELECT id, name, parent FROM category"; $res = $db->query($sql); // // store arrays of items for each parent in an array // while (list($id, $name, $parent) = $res->fetch(PDO::FETCH_NUM)) { $data[$parent][] = array('id'=>$id, 'name'=>$name); } /** * recursive function to print a category then its child categories * * @param array $arr category data * @param int $parent parent category * @param int $level hierarchy level */ function displayHierarchy(&$arr, $parent, $level=0) { if (isset($arr[$parent])) { echo "<ul>\n"; foreach($arr[$parent] as $rec) { echo "<li class='li$level'>{$rec['name']}\n"; if (isset($arr[$rec['id']])) displayHierarchy($arr, $rec['id'], $level+1); echo "</li>\n"; } echo "</ul>\n"; } } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Example</title> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript"> </script> <style type="text/css"> body { font-family: verdana,sans-serif; font-size: 11pt; padding: 50px; } li { font-weight: 600;} .li0 { color: red; } .li1 { color: green; } .li2 { color: blue; } </style> </head> <body> <?php displayHierarchy($data, 0); ?> </body> </html>
    2 points
  20. try foreach ($array as $k => $d) { if ($k > 0) { if (strtotime($d) > strtotime($array[$k-1])+6) { $new[] = "-------------------"; } } $new[] = $d; } $new = Array ( [0] => 2021-02-10 09:04:48 [1] => 2021-02-10 09:04:54 [2] => 2021-02-10 09:05:00 [3] => 2021-02-10 09:05:06 [4] => 2021-02-10 09:05:12 [5] => 2021-02-10 09:05:18 [6] => ------------------- [7] => 2021-02-10 09:06:18 [8] => 2021-02-10 09:06:24 ) [edit...] Alternative solution... $new = []; $newkey = 0; foreach ($array as $k => $d) { if ($k > 0) { if (strtotime($d) > strtotime($array[$k-1])+6) { $newkey++; } } $new[$newkey][] = $d; } gives $new = Array ( [0] => Array ( [0] => 2021-02-10 09:04:48 [1] => 2021-02-10 09:04:54 [2] => 2021-02-10 09:05:00 [3] => 2021-02-10 09:05:06 [4] => 2021-02-10 09:05:12 [5] => 2021-02-10 09:05:18 ) [1] => Array ( [0] => 2021-02-10 09:06:18 [1] => 2021-02-10 09:06:24 ) )
    2 points
  21. That's why I laid it out the way I did with the comments - so it would be easy for you get the separate feet/inches values if you still wanted to go that way. [edit] Look more closely at my code - you require two substring_index()s to extract the inches. The inner to get the string before the final " and the outer one to get the string after the ' SET feet = substring_index(@height, '\'', 1) * 12 , inches = substring_index(substring_index(@height, '"', 1), '\'', -1)
    2 points
  22. NOTE: both instances of $db->query(..) in the above post should be $db->prepare(..)
    2 points
  23. However, using the string just as far as the the first entity $valrD = json_decode(valrGet, true); echo '<pre>$valrD = ', print_r($valrD, 1), '</pre>'; gives therefore $target = 'BTC/ZAR'; foreach ($valrD['response']['entities'] as $k => $ents) { if ($ents['pair_name'] == $target) { echo "$target asking price : {$ents['ask']['price']}<br>"; break; } } outputs "BTC/ZAR asking price : 179382.54"
    2 points
  24. if ($success) { $_SESSION["userLoggedIn"] = $username; header("Location:index.php"); }else{ $error = $account->getError(Constants::$registerFailed); } It's a good practice to use an exit after the header ("Location ...
    2 points
  25. 1 and 2 would presumably be input from the web page. The rest would be something like: for ($m=1; $m<=$M; $m++) { for ($l=1; $l<=$L; $l++) { for ($j=1; $j<=$N; $j++) { #do calculation here storing it in a 2D array } # select minimum here (perhaps min() function) } } # use array sort # use PHP vector class # compute distance from vectors # echo results in desired format
    2 points
  26. You are missing the step to prepare the query before binding the parameters. I would strongly advise you use PDO rather than mysqli - much simpler.
    2 points
  27. code that unconditionally (always) outputs the raw database statement errors for the connection, query, prepare, and execute statements, only helps hackers when they intentionally trigger errors, since these errors contain things like the database hostname/ip address, database username, if a password is being used or not, part of the sql syntax, and web server path information. the only time you should output the raw database statement errors is when learning, developing, or debugging code/query(ies) and you are viewing the site as the developer/programmer. at all other times, you should log these errors. the simple way of doing this is to use exceptions for errors and in most cases let php catch and handle the exception, where php will use its error related settings to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.) you would then remove any discrete error handling logic, since it doesn't add any value for a legitimate visitor to your site, and it will no longer get executed when there is an error (execution transfers to the nearest exception handler for the type of exception or to php if there is none.) the line that Barand posted enables exceptions for errors for the mysqli extension.
    2 points
  28. foreach ($global_array as $k => $v) { foreach ($global_array as $k1 => $v1) { if ($k==$k1) continue; if (array_values(array_intersect($v, $v1)) == array_values($v1)) { unset($global_array[$k1]); } } }
    2 points
  29. Don't worry about the IBD file. MySQL knows how to manage itself, you don't need to go second guessing it because of what you think you saw in Notepad. The question you think you're asking is whether to use an UPDATE or a DELETE+INSERT, but the question you're actually asking is how you should manage uploaded files that can be replaced. The answer to that is... well, it depends. There are two basic options: 1. Forget the previously uploaded file. You don't care about it. Take the new file and stick it wherever you want, update the database, and delete the old file. Gotta delete. Because if you forget about the old file then there's not much of a point to keeping the file itself around too. 2. Keep track of the previous file. You'd probably want a table that holds all the information for past and future uploads, and that's where you track them. For using those files, instead of storing the file information in whatever place, you reference the file in your upload information table. New image, new information row, and you update whatever place was affected. This lets you keep a history of everything, which probably isn't important for stuff like user avatars but is frighteningly important for stuff like monetary transactions. "Okay, I've decided that I want to do <whichever option>. But what about my literal question? Should I update or delete and insert?" Time to learn about an important concept in computing that disappointingly few programmers ever end up learning: atomicity. That's the noun version of "atomic", which means (in this case) that whatever operation you need to do can't be interrupted or broken in half or appear to anyone else as being anything less than one single action. Atomicity is important for stuff like files and databases because you basically never want to look at a file or data in the middle of some important operation. Imagine your site is popular. Really popular. Facebook or Twitter popular. Constant traffic to your servers. Now imagine a user uploads a new image. When the code is ready, it needs to go off into the database to make whatever changes it needs to make so the user has the new image. Say you go with DELETE and INSERT. Your code runs one query that DELETEs whatever, then another query that INSERTs. Sounds fine. Except remember how your site is always busy? It's quite possible someone was looking at your site at the moment in between those two queries. Since the DELETE has happened but not yet the INSERT, your code isn't going to find whatever data it needed to find and the user is going to get a bad experience. If that user was a CEO for a huge company that wanted to buy you out for lots of money, they might not do that now. A DELETE and INSERT is not atomic because there was that point in between the two queries. It was not "one single action". Instead you go with UPDATE. The database does whatever it does, but the clever people who wrote the software for it already knew about stuff like atomicity. And they made their system guarantee that UPDATEs are atomic. One single action. If you do an UPDATE when that rich CEO looks at your site, the database has guaranteed to you that either (a) the CEO will see the old data because the update hasn't happened yet, or (b) they'll see the new data because the update has happened. There is no moment in between old and new for stuff to be broken.
    2 points
  30. I just didn't see the table - the end of that first line was somewhere in my neighbour's living room.
    2 points
  31. I totally agree with @requinix regarding the two tables. However, if you are willing to compromise over the output, you could do something like this SELECT uid , name , SUM(CASE payment_type WHEN 'cash' THEN payment ELSE 0 END) as cash , SUM(CASE payment_type WHEN 'card' THEN payment ELSE 0 END) as card , cost , cost-SUM(payment) as balance FROM payment GROUP BY uid +------+------+------+------+------+---------+ | uid | name | cash | card | cost | balance | +------+------+------+------+------+---------+ | 1 | kim | 0 | 100 | 100 | 0 | | 2 | lee | 95 | 0 | 95 | 0 | | 3 | kent | 50 | 50 | 100 | 0 | | 4 | iya | 40 | 20 | 80 | 20 | +------+------+------+------+------+---------+ If you really need every transaction listed, the SQL becomes quite complex involving user variables and subqueries. It would be much easier to do in the PHP as you output each row. [EDIT] ... For the sake of completeness SELECT uid , name , cash , card , cost , cost-total as balance FROM ( SELECT name , CASE payment_type WHEN 'cash' THEN payment ELSE 0 END as cash , CASE payment_type WHEN 'card' THEN payment ELSE 0 END as card , cost , @tot := CASE @previd WHEN uid THEN @tot + payment ELSE payment END as total , @previd := uid as uid FROM ( SELECT * FROM payment ORDER BY uid ) sorted JOIN (SELECT @previd:=0, @tot:=0) initialize ) recs; +------+------+------+------+------+---------+ | uid | name | cash | card | cost | balance | +------+------+------+------+------+---------+ | 1 | kim | 0 | 100 | 100 | 0 | | 2 | lee | 95 | 0 | 95 | 0 | | 3 | kent | 50 | 0 | 100 | 50 | | 3 | kent | 0 | 50 | 100 | 0 | | 4 | iya | 40 | 0 | 80 | 40 | | 4 | iya | 0 | 20 | 80 | 20 | +------+------+------+------+------+---------+
    2 points
  32. the convention around here is "New question, new thread". That allows for short, direct answer to short, direct questions instead of long, rambling threads where all the "Goodness" gets lost. Some comments on the above: the use of "global" breaks encapsulation, requiring the environment "outside" the function to provide the variable. It is better to pass the data as an argument to the function. What value does admin['gender'] have? Any value passed that resolves to true will cause the ternary operator to return "Mr" and everything else will return "Mrs". The code makes no attempt to ensure that the array indexes used actually exist; this may or may not be an issue. What if the individual is female and not married? They might object to being called "Mrs". What if the individual is not gender-identifying? They would object most strongly to be referred to by either of the terms used here. Marital status and/or gender are both Personal Data and should be stored in the User's "record" (whatever form that takes) so that it can be managed by/on behalf of the User and changed over time. Regards, Phill W.
    2 points
  33. This example uses glob() to get all .png and .jpg in a folder. By default, the folder is assumed to be named "images" and is a subdirectory of the folder containing the script. Images are displayed as thumbnails, 5 in each row with 25 per page. <?php session_start(); const IMGDIR = 'images/'; const PERPAGE = 25; $page = $_GET['page'] ?? 1; $imgdir = $_GET['dir'] ?? IMGDIR; if (!isset($_SESSION['imgdir']) || $_SESSION['imgdir'] != $imgdir) { unset($_SESSION['images']); $_SESSION['imgdir'] = $imgdir; $page = 1; } if (!isset($_SESSION['images'])) { $_SESSION['images'] = glob($imgdir.'{*.png,*.jpg}', GLOB_BRACE); // get .jpg and .png images } $total = count($_SESSION['images']); /** ************************************************************************************** * display paginated images from SESSION['images] * * @param int $page * @param int $perpage */ function displayImages($page, $perpage) { $start = ($page - 1) * $perpage; $ilist = array_slice($_SESSION['images'], $start, $perpage); foreach ($ilist as $i) { $n = trim(basename($i)); list($iw, $ih,, $sz) = getimagesize($i); if ($iw >= $ih) { // landscape $w = 150; $h = 150 * $ih/$iw; } else { // portrait $h = 150; $w = 150 * $iw/$ih; } $alt = substr($n, 0, 15); echo " <div class='image'> <img src='$i' height='$h' width = '$w' alt='$alt'> </div> "; } echo "<div style='clear:both'></div>"; } /** ************************************************************************************ * function to output page selection buttons * * @param int $total total records * @param int $page current page number * @return string selection buttons html */ function page_selector($total, $page) { if ($total==0) { return ''; } $kPages = ceil($total/PERPAGE); $filler = '&nbsp;&middot;&nbsp;&middot;&nbsp;&middot;&nbsp;'; $lim1 = max(1, $page-2); $lim2 = min($kPages, $page+3); $p = $page==1 ? 1 : $page - 1; $n = $page== $kPages ? $kPages : $page + 1;; $out = "$kPages page" . ($kPages==1 ? '' : 's') . " &emsp;"; if ($kPages==1) { return $out; } $out .= ($page > 1) ? "<div class='pagipage' data-pn='$p'>Prev</div>&ensp;" : "<div class='pagipage x' data-pn='$p' disabled>Prev</div>&ensp;"; if ($page > 4) { $out .= "<div class='pagipage' data-pn='1'>1</div> $filler"; } elseif ($page==4) { $out .= "<div class='pagipage' data-pn='1'>1</div>"; } for ($i=$lim1; $i<=$lim2; $i++) { if ($page==$i) $out .= "<div class='pagicurrent'>$i</div>"; else $out .= "<div class='pagipage' data-pn='$i'>$i</div>"; } if ($page < $kPages-3) { $out .= "$filler <div class='pagipage' data-pn='$kPages'>$kPages</div>"; } $out .= $page < $kPages ? "&ensp;<div class='pagipage' data-pn='$n'>Next</div>" : "&ensp;<div class='pagipage x' data-pn='$n' disabled>Next</div>"; return $out; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="content-language" content="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="author" content="B A Andrew"> <meta name="creation-date" content="11/29/2019"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <title>Example</title> <script type="text/javascript"> $().ready( function() { $(".pagipage").click( function() { $("#page").val( $(this).data("pn") ) $("#form1").submit() }) }) </script> <style type="text/css"> body { font-family: verdana, sans-serif; font-size: 11pt; } label { display: inline-block; width: 150px; font-weight: 600; } #image_wrapper { margin: 30px; } .image { width: 18%; min-height: 200px; margin: 10px; float: left; text-align: center; padding: auto;} /* pagination styles */ .pagipage { display: inline; width: 25px; height: 15px; padding: 3px 5px; text-align: center; font-size: 9pt; border: 1px solid #BB9A21 ; color: #BB9A21; background-color: #FFF; cursor: pointer; margin-left: -1px; } .pagipage.x { background-color: #CCC;} .pagipage:hover { background-color: #BB9A21; border-color: #F0F; color: white; } .pagicurrent { display: inline; width: 25px; height: 15px; text-align: center; font-size: 9pt; font-weight: 600; border: 1px solid #BB9A21; background-color: #BB9A21; color: white; padding: 3px 5px; } .paginate_panel { text-align: center; margin: 20px 0; width: 100%; color: #BB9A21; } </style> </head> <body> <header> <h1>Example Image List</h1> </header> <form id="form1"> <fieldset> <label>Image Folder</label> <input type="text" name="dir" value="<?=$imgdir?>" size="80"> <input type="hidden" name="page" id="page" value="<?=$page?>"> <br> <label>&nbsp;</label> <input type="submit" name="btnSubmit" value="Submit"> </fieldset> </form> <div class='paginate_panel'> <?=page_selector($total, $page, PERPAGE)?> </div> <div id="image_wrapper"> <?=displayImages($page, PERPAGE)?> </div> <div class='paginate_panel'> <?=page_selector($total, $page, PERPAGE)?> </div> </body> </html>
    2 points
  34. Yes but you don't want to run both at the same time. If you really wanted to, you would need to change the Apache port on one of them as they both use port 80
    2 points
  35. It depends on the collation setting for the column.
    2 points
  36. Protecting a form field from what? htmlspecialchars() is for use when outputting user-supplied data data to a web page. mysql_real_escape string() is was used to protect input values to queries from SQL injection. This is now obsolete, replaced by mysqli_real_escape_string() or (better still) the use of prepared statements to completely separate the query code from the user-supplied data.
    2 points
  37. Store the info that the user put in the original QR code. User retrieves and edits the data, then generates new QR code.
    2 points
  38. I have been playing around with a possible database solution to your problem Given that a postcode such as "EH12 3AB" breaks down into four parts viz +------+----------+--------+------+ | area | district | sector | unit | +------+----------+--------+------+ | EH | 12 | 3 | AB | +------+----------+--------+------+ ... I was toying with this table structure CREATE TABLE `postcode` ( `pc_id` int(11) NOT NULL AUTO_INCREMENT, `seller` int(11) DEFAULT NULL, `area` varchar(2) DEFAULT NULL, `district` varchar(2) DEFAULT NULL, `sector_min` char(1) DEFAULT NULL, `sector_max` char(1) DEFAULT NULL, `unit_min` char(2) DEFAULT NULL, `unit_max` char(2) DEFAULT NULL, `deliverable` tinyint(4) DEFAULT NULL, `price` decimal(8,2) DEFAULT NULL, PRIMARY KEY (`pc_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ | pc_id | seller | area | district | sector_min | sector_max | unit_min | unit_max | deliverable | price | +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ | 1 | 1 | EH | 1 | 1 | 4 | AA | ZZ | 1 | 1.50 | | 2 | 1 | EH | 1 | 5 | 5 | AA | BZ | 1 | 1.80 | | 3 | 1 | EH | 1 | 5 | 5 | CA | ZZ | 0 | 2.00 | | 4 | 1 | EH | 2 | 1 | 9 | AA | ZZ | 1 | 2.25 | | 5 | 1 | EH | 3 | 1 | 9 | AA | PZ | 1 | 2.50 | +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ My code was $postcodes = [ 'EH1 2DB', 'eh15bg' , 'eh1 5ba', 'eh15dg', 'EH2 7HJ', 'EH3 2PT', 'EH3 8SX', 'EH146DE' ]; echo '<pre>'; foreach ($postcodes as $pc) { vprintf('%s%s %s%s : %s<br>', deliveryPrice($db, $pc)); } echo '</pre>'; function deliveryPrice($db, $pcode) { $pcode = strtoupper(str_replace(' ', '', $pcode)); $area = $district = ''; $sector = substr($pcode,-3, 1); $unit = substr($pcode, -2); $l = strlen($pcode); $first = str_split(substr($pcode, 0, $l-3)); foreach ($first as $c) { if (ctype_digit($c)) { $district .= $c; } else { $area .= $c; } } $res = $db->prepare("SELECT price FROM postcode WHERE area = ? AND district = ? AND ? between sector_min AND sector_max AND ? BETWEEN unit_min AND unit_max AND deliverable "); $res->execute( [ $area, $district, $sector, $unit ] ); $p = $res->fetchColumn(); $price = $p ? number_format($p, 2) : 'N/A'; return [$area, $district, $sector, $unit, $price ]; } RESULTS: EH1 2DB : 1.50 EH1 5BG : 1.80 EH1 5BA : 1.80 EH1 5DG : N/A EH2 7HJ : 2.25 EH3 2PT : 2.50 EH3 8SX : N/A EH14 6DE : N/A
    2 points
  39. You need to specify your units for the margin values. 161px, not just 161.
    2 points
  40. If this is a repetitive project that is going to build all of the mentioned arrays every time it is executed, perhaps you should consider not having to re-build your second array by using the SKU as the index value of the first array and avoid creating the 2nd array. Change this: $product_table[] = ['SKU' => $sku, 'Label' => $attribute_name, 'Value' => $term_obj->name ]; to: $product_table[$sku][] = ['Label' => $attribute_name, 'Value' => $term_obj->name ];
    2 points
  41. You may find my reply to one of your previous topics of interest here. (I sometimes ask myself why we bother)
    2 points
  42. here's a list of things i saw in the posted code - 1. don't put php variables inside of double-quotes if they are the only thing in the string. 2, don't use or die() for error handling. use exceptions and in most cases let php catch the exception. note: your use of mysqli_error(...) in the connection code won't work because there's no connection to use. 3. don't unconditionally output database errors onto a web page (this will go away when you get rid of the or die() logic.) 4. don't run queries inside of loops. learn to do JOIN queries. 5. if your code is tabbed that far over because it is located inside your html document, you need to put the php code that's responsible for getting/producing data before the start of your html document, fetch the data into appropriately named php variable(s), then use those variable(s) in the html document. 6. handling the negative/failure case is usually shorter then the positive/successful case. if you invert the logic tests and handle the negative/failure condition first, your code will be clearer. you won't have logic for the negative/failure case 10's/100's of lines later in the code. 7. don't use loops to fetch what will be at most one row of data. just directly fetch the single row of data. 8. don't put static calculations inside of loops. the various date values shouldn't change during one report (where they are at now, they will if the request spans midnight.) put them before the start of the loop. 9. don't put quotes around numbers. 10. don't selected things that are not used and don't create variables that are not used (given the amount of code, the cases i saw of this may not be accurate.) 11. if you are looping to do something (should go away with JOINed queries), don't evaluate count() statements in the loop. determine the loop count, once, before the start of the loop. 12. doing some of these things will simplify variable naming. you won't have to think up unique names for variables because you will only have one instance in the code. 13. the $AffID is probably from external/unknown data. you should NOT put eternal/unknown data directly into an sql query statement. use a prepared query, with a place-holder for each data value, then supply the data when the query gets executed. switching to the much simpler php PDO extension will make using prepared queries easy compared to the php mysqli extension.
    2 points
  43. It also doesn't say so on the documentation for explode() or mysqli_connect(). That function is part of the GeoIP package, which has a whole section dedicated to setting it up.
    2 points
  44. OR if you use the same named hidden field for all the forms, 'action' for example, each with a unique value, you can eliminate any isset() tests for that field since it will be set if the request method is post.
    2 points
  45. So we all (most of us) know some CSS. You might not consider yourself a web designer, be fluent with all the popular libraries, but you know your way around how to do it. Like if you want to make something bold you could inline it <span style="font-weight:bold;">An important statement</span> but you're smarter and you know you should .bold { font-weight: bold; } <span class="bold">An important statement</span> A trivial example, of course, but it demonstrates how you should use CSS. Right? No. God damn *#(*^y$&#ing NO. So maybe it's a bad example. People don't actually do that. Okay. Let's look at some official Bootstrap examples instead. <button type="button" class="btn btn-lg btn-default">Default</button> No. <table class="table table-striped"> Stop that. <ul class="list-group"> <li class="list-group-item">Cras justo odio</li> Dude. What's the problem here? You're restating the obvious! I know that button is a button. It's got #*^(ing "button" right in the (*^-@$ markup. Ooh, it's a LARGE button. Wow! And hey, that table has stripes? Amazing! And you mean to tell me that UL is a list and the LI is an item? You're blowing my mind! You're also DOING IT WRONG. The power behind CSS is (a) not having to tell the browser that yes, in fact, that button really is a button, and (b) not having to say the same thing over and over again in different places. And that is where Bootstrap fails miserably. You want to create a button? Go ahead. Create the button. Then throw a few classes at it so it looks the way you want. Want another button? Create another button and throw classes at that one too. Created a button and it doesn't look right? Oh damn, you forgot one of the classes you have to include. Ha ha, oops. "But that's how CSS should be used!" No. You're all missing the (*@#*^ing point and making everything hard on yourself and the people who have to deal with your crap. What if I want to add a dropdown list of items? What should I do? The page already has a couple dropdowns on it so I know the styling is in place. I'll add a simple <select> and... nope, looks like a plain list. No styling applied. What happened? What happened is that I didn't apply the handful of classes necessary to make the list appear like the damn list it should already be. What happened is that I forgot I have to add in the presentation aspects to my HTML. And that's what this whole stupid thing boils down to: people can't shift their mindset away from the presentation, and while they know not to mix presentation with markup they've not noticed that all they did was trade one syntax for another. The problem is still (@^$ there. "Oh, right, yeah, if you're so smart then how would you do it?" Thank you for asking. You want a button. You want a large button. You want a large button that draws peoples' eyes to it because it's the button they probably want to use and so it's the default. That's presentation. Forget about presentation. You want a default button. That's it. That's all you should have to care about. <button type="button" class="default">Default</button> Done. "But no, it doesn't look the way I want!" I don't give a damn how you want it to look. I want to know what the button means. What is the significance behind the button. What does it represent. Because ultimately that's what the HTML markup needs to concern itself with. Write semantic markup and leave out the presentation crap because it has no place in the document. "Oh, so you think we shouldn't have any CSS at all or what?" Take those words out of my mouth before I cram them back down yours. button { /* make it look like a nice button */ } button.default { /* blue or whatever */ } There. Now the presentation is accounted for in the @(!^)$ place where it should be: CSS. And if I want to add another default button somewhere I don't have to look up the Bootstrap reference because I don't remember which 5 classes are relevant. Default button? Default button. The only way this could improve is if HTML added a way to actually identify the default button of a form, in which case that class=default goes right out the damn window and the CSS targets that new attribute or whatever it is instead. "Noo, it's not a large button!" Alright. Fine. Let me take a deep breath before I have to deal with you. So. Why do you want it to be large? Don't give me some stupid reason like "because I want it to be large". What is the reason behind making it large? What decision process did you go through in your head that resulted in the button needing to be larger? Why is the normal size for buttons not appropriate? Maybe the form is a modal and you want larger buttons? Okay. Did you mark the form as modal? Because that's the first thing you have to do. <form class="modal"> form.modal button { /* larger */ } And done. Problem solved. Problem solved in a way that keeps the appearance of the button separate from the markup of the button. Want to add another button to the modal? Go on. Add another stupid button. One that doesn't require any classes just because it's supposed to be larger. What you might be able to realize here is that now I've established a rule saying "buttons in modal forms are larger". And it applies everywhere you have a modal form. If you make another modal form then magically the buttons are larger there too! And without having to find that first place you had that one modal form, what page was that again, oh right, over here, now what classes and CSS files did I have to use for it to make it look that way, oh right, those classes. How about a striped table? Why is it striped? Because it's a table that will grow vertically and has enough data in its columns that people need help scanning through them? So what you're telling me is that the table is, say, "dense"? <table class="dense"> table.dense > tbody > tr:nth-child(odd) { /* striped */ } Somehow I'm able to rub a couple brain cells together and end up with a way of identifying the table for what it is and not what I want it to look like on the page. How about a regular list? Nothing special? <ul> <li>Cras justo odio</li> Nothing (*&^!@ special. Now when I come along, I can write markup into your fancy page you spent a couple days tweaking until it looked oh so pretty, and I don't have to run off to the kitchen where I can cool my heels instead of planning your "accidental" death because I can write simple, logical, and minimal HTML that represents what I'm adding without having to fire up five different browsers to see that I got all the required classes. What's more, if someone decides that modal dialogs on mobile devices need to look a little different, I don't have to spend a day searching the codebase for anything modal because the work has gone from "go fix all the modal dialogs to use this new CSS class someone wrote" to "apply media queries to adjust the existing modal dialog to better suit mobile screens". This isn't damn rocket science. I know you web designers had a hard time in college with your liberal arts degree and that's it's so unfair you have to work with computer graphics instead of living in a loft painting bowls of fruit all day, but surely even you are smart enough to understand these principles. Stop thinking with your eyes and start thinking with your brain. And now I go back to work. Dealing with stupid crap. That I put off by ranting about it here.
    2 points
  46. As you are sorting on "name", which is the first element of the sub-arrays, you can just use an ordinay sort() or rsort() call. (By default it will sort on the values oof the first element) EG $tadminlist["pvp"] = [ [ 'name' => 'mapname1', 'type' => 'pvp', 'beta' => 'y', 'final' => 'n', 'modded' => '', 'classification' => 'land', 'sf' => 'n', 'tod' => 'dawn', 'weather' => 'fog', 'es2' => 'y' ], [ 'name' => 'mapname3', 'type' => 'pvp', 'beta' => 'yy', 'final' => 'n', 'modded' => 'y', 'classification' => 'air', 'sf' => 'y', 'tod' => 'day', 'weather' => 'rain', 'es2' => 'n' ], [ 'name' => 'mapname2', 'type' => 'pvp', 'beta' => 'n', 'final' => 'y', 'modded' => 'n', 'classification' => 'sea', 'sf' => 'n', 'tod' => 'night', 'weather' => 'clear', 'es2' => 'n' ], ]; echo "line = " . join(', ', array_keys($tadminlist["pvp"][0])) . '<br><br>'; listData($tadminlist["pvp"]); echo "<br>SORTED ASC<br>"; sort($tadminlist["pvp"]); listData($tadminlist["pvp"]); echo "<br>SORTED DESC<br>"; rsort($tadminlist["pvp"]); listData($tadminlist["pvp"]); function listData($arr) { foreach ($arr as $tlist) echo join(', ', $tlist) . '<br>'; } OUTPUTS line = name, type, beta, final, modded, classification, sf, tod, weather, es2 mapname1, pvp, y, n, , land, n, dawn, fog, y mapname3, pvp, yy, n, y, air, y, day, rain, n mapname2, pvp, n, y, n, sea, n, night, clear, n SORTED ASC mapname1, pvp, y, n, , land, n, dawn, fog, y mapname2, pvp, n, y, n, sea, n, night, clear, n mapname3, pvp, yy, n, y, air, y, day, rain, n SORTED DESC mapname3, pvp, yy, n, y, air, y, day, rain, n mapname2, pvp, n, y, n, sea, n, night, clear, n mapname1, pvp, y, n, , land, n, dawn, fog, y To sort by any other element would require usort, eg to sort by classification usort($tadminlist["pvp"], function($a, $b) { return $a['classification'] <=> $b['classification']; } );
    2 points
  47. Alternative for Windows users with no money_format() function $prices = [ 39.99, 35.99, 69.99, 89.99 ]; function deu_money($n) { return '&euro;'.number_format($n, 2, ',', '.'); } $prices = array_map( 'deu_money' , $prices); giving $prices Array ( [0] => €39,99 [1] => €35,99 [2] => €69,99 [3] => €89,99 )
    2 points
  48. Take a look at these two lines of code $row = mysqli_fetch_assoc($result); while($row = mysqli_fetch_assoc($result)){ and tell your rubber duck what they are doing.
    2 points
  49. I found it here Or did you have something more like this in mind? Save this code as "stave.svg" <svg width="1000" height="200" viewBox="0 0 1000 200"> <defs> <style type="text/css"> .trebleclef { fill: black; font-size: 50pt; } .bassclef { fill: black; font-size: 40pt; } .curly { fill: black; stroke: none; font-size: 110pt; font-weight: 100; } .stave { stroke-width: 1px; stroke: gray; fill: none; } </style> </defs> <!-- treble --> <line x1='40' y1='30' x2='960' y2='30' class='stave' /> <line x1='40' y1='38' x2='960' y2='38' class='stave' /> <line x1='40' y1='46' x2='960' y2='46' class='stave' /> <line x1='40' y1='54' x2='960' y2='54' class='stave' /> <line x1='40' y1='62' x2='960' y2='62' class='stave' /> <text x='44' y='65' class='trebleclef'>&#x1D11E;</text> <!-- bass --> <line x1='40' y1='130' x2='960' y2='130' class='stave' /> <line x1='40' y1='138' x2='960' y2='138' class='stave' /> <line x1='40' y1='146' x2='960' y2='146' class='stave' /> <line x1='40' y1='154' x2='960' y2='154' class='stave' /> <line x1='40' y1='162' x2='960' y2='162' class='stave' /> <text x='44' y='165' class='bassclef'>&#x1D122;</text> <!-- stave ends --> <text x='-20' y='132' class='curly'>{</text> <path d="M 40 30 L 40 162" class='stave' /> <path d="M 960 30 L 960 162" class='stave' /> </svg> Then, in your html <div><?php include 'stave.svg'?></div> <div><?php include 'stave.svg'?></div> <div><?php include 'stave.svg'?></div> Which should give you
    2 points
This leaderboard is set to New York/GMT-04: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.