Jump to content

boen_robot

Members
  • Posts

    8,493
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by boen_robot

  1. boen_robot

    session start

    You could fetch some data from the DB upon login, and store it in the session (from which point you'd use just the session), thus reducing the overall load on the DB server... But you don't have to do that, and should the database be updated in the mean time, your session will still be using the old data (unless it checks for updates, but that would defeat the whole purpose), and this will continue until the end of the session (via a timeout or an explicit "log out", i.e. "session_destroy();").
  2. "Language" as in "keyboard layout" or "spell check"?If you're talking about keyboard layout... You can't really do that. That's up to the user's keyboard settings. The closest thing to that you can do is detect the key pressed, and emulate a different keyboard layout based on a user selection. Depending on the browser used, this could backfire (=> the user would enter the character configured at their keyboard settings). You can do that using JavaScript. Attach an "onkeydown" event, check the pressed key from the event's "keyCode" property, append the character that corresponds to it (NOT the "charCode" character - this is the character based on the user's current keyboard settings), and return false to prevent the original character from being written.
  3. How many times do we have to tell you? You're using "(" for the if/else bodies, when you should instead be using "{", and that is causing the error.Try this: <?php$allowedExts = array("jpg", "jpeg", "gif", "png");$chunks = explode(".", $_FILES["file"]["name"]);$extension = end($chunks);if ( ( $_FILES["file"]["type"] == "image/gif" || $_FILES["file"]["type"] == "image/jpeg" || $_FILES["file"]["type"] == "image/pjpeg" ) && $_FILES["file"]["size"] < 20000 && in_array($extension, $allowedExts)) { if ($_FILES["file"]["error"] > 0) { echo "Return Code: " . $_FILES["file"]["error"] . "<br />"; } else { echo "Upload: " . $_FILES["file"]["name"] . "<br />"; echo "Type: " . $_FILES["file"]["type"] . "<br />"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />"; echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />"; } if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " already exists. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); echo "Stored in: " . "upload/" . $_FILES["file"]["name"]; }} else { echo "Invalid file";}?> Look closely at the stuff before and after "else", and see what you're using instead.
  4. boen_robot

    CGI ?

    CGI isn't really a language, but a protocol for applications. PHP is a CGI application. Or to be more precise, it can be used as a CGI application.Most other languages that have a CGI reputation (Ruby, Perl) aren't exactly CGI applications themselves... but they do allow you to output CGI compatible output.In fact, if you run a PHP from "php.exe", and output HTTP headers using "echo", you are in essence creating a CGI application.
  5. You may want to consider using a CDN service for the files (or a Cloud service for the whole thing), but if you insist on using your own architecture, fine...It's generally a good idea to have a central distribution server that would do the job of copying files across all of your servers (which, obviously, would be listed there, with sufficient permissions, credentials, etc.). Each of your web servers, once it receives a file from a user, will upload the file to the distribution server, so that it can go to all other "mirrors". To keep the web application responsive, the upload to the distributor should happen by a separate application on that server, which would monitor the upload folder.To spread the load between your server, you'd need to have at least one "load balancer" device, through which all connections will pass. The only job for this device is to spread the TCP connections it receives across all of your servers listed in it. I say "at least" one, because you can have few, and your DNS servers (of which, AFAIK, you can have up to 5) could point all clients to any and all of them.The DNS servers themselves, although always equal in weight, may, and should, be located on different parts of the globe, and contain only the IPs of your servers that are near them. They could of course check if the servers are reachable, and use distant servers otherwise.
  6. boen_robot

    session start

    ... In other words, you need to call session_start() near the start of every page from which a user could be logged in or not. And you do that to enable yourself to act differently based on whether they are logged in and/or who exactly is logged in.Since every $_SESSION starts empty, you can safely assume that if it's empty, the user is not logged in yet. Upon successful login, you'd fill out some key with some value (by convention, people enter the username as a value, but like any convention, that's not a must). So when you later call session_start() and find $_SESSION to contain the key, you know there was a successful login at an earlier point in time.In addition to using $_SESSION as this "is the user logged in?" indicator, you can also use it for any data that needs to persist between pages, but not between logins. A typical use case is in shopping application, where the $_SESSION contains the current items in the "cart" before they are checked out.
  7. boen_robot

    json_decode

    Yeah, the built in JSON functions are sketchy like that.In PHP 5.4.0, they introduce an options parameter that lets you explicitly specify if you want big ints as floats or as strings, with the default (in THAT version) being conversion to floats. Now that there is an option, things are unlikely to change again.The most cross-version way (if you're after that) is to manually check the output of json_decode with is_numeric, and attempt to cast to float if possible. But that's kind'a useless in a loosely typed language like PHP.
  8. No.The very idea of the "if" is to prevent exactly THAT scenario.When output_header gets called, it checks if it can call the inner function, and calls it only if it can. A boolean false does not translate to a function that can be called, so no function is ever called within output_headers in that case.
  9. Me and birbal already gave you the solution. I even wrote down the code here.
  10. Yes, but within the function, the $function argument is called like a function. In other words, we're talking about the use of the argument, not the syntax of its declaration (which is fine). The phrase "call it like a function" refers to the line$function($username); THAT is calling a variable/argument like a function. If $function is set to 'output_header_list', then the above is equivalent to having output_header_list($username); in place of that line.
  11. The way output_header() is currently written, the value of the first function is ALWAYS treated as the name of a function to be called, and the second argument is ALWAYS passed to that function.Your default values to both are false, but what this means is that PHP tries to call a function with a name that is a boolean false, which makes no sense, hence the error.You need to "manually" check if what you're given is the name of a function, or another arbitrary value (whether that's a boolean false, null, or a string that isn't a function name), and act accordingly. So for example, instead of <?php $function($username); ?> you can have <?php if (is_callable($function)) { $function($username);} ?> Which would mean that if $function does not contain the name of a real function, nothing will happen.
  12. 4. "Advanced" debugging techniques for any PHP code (In reality, these things aren't "advanced" as in "difficult to grasp", but they do require some extra setup, hence they're not really "basic" either) 4.1. Use an editor with "syntax highlighting" for PHPJust because PHP can be written with just Notepad doesn't mean that you have to use it. In fact, it's a bad idea to do so, unless of course you have no other choice. There are countless other editors, and if you just search "PHP editor", you'll get a large list of editors, all of which have a feature known as "syntax highlighting". What this means is that the editor will color different parts of your code differently, based on what PHP is expected to interpret that part as. It might sound like just a silly cosmetic, but that's in fact the quickest way of finding syntax/parse errors in your code. For example, if you know that your editor colors strings as one color and loops with another, yet see a loop with the color of a string, you already know that you have a string above the loop that you haven't closed. Vice versa? You probably forgot to close another string above the mis-colored string. No colors? Chances are you're not within a "<?php" block. Unconvinced? This forum has a syntax highlighting feature built in if you use the "code" BBCode tag. It tries to guess the language, and color accordingly. An explicit "<?php" is enough to make it turn on PHP. Next time you have a syntax/parse error, "Preview" your post, where the code is surrounded in a "code" BBCode tag, and see if you can spot your error. While we're on the subject of editors... 4.2. Prefer editors with "code completion" for PHP What "code completion" (sometimes called "auto complete", "Intellisense" or other kinds of marketing nonsense) means is the ability of an editor to suggest possible things you may be trying to type. In addition to saving you time in typing new code, this ability is also useful for debugging - if you can't see a variable/function/class/whatever in the list of suggestions, chances are that you've mistyped it and/or that the editor is smart enough to know that you can't use that thing at that point. There aren't many editors with "code completion" for PHP, due to the fact that PHP is loosely typed and interpreted, which means that more often than not, anything could potentially be everything everywhere (simply put, things become known when you run the file, not while you're typing it), which means that editors need to be a lot smarter, and allow themselves the potential of giving you wrong information (and we don't want that, do we?). If you keep your code organized and in small isolated compositions (functions, classes, methods, etc.), use type hinting everywhere it makes sense, and use "DocBlocks" to document all of your code, you probably won't encounter misleading editor hints. Some editors with "code completion" for PHP include Adobe Dreamwaver CS6 (earlier versions only support it for built-in PHP functions and nothing more, while this version also includes support for PHP classes and your own functions/classes), NetBeans (7.2 also supports traits), PhpStorm, Eclipse PDT and Aptana Studio. 4.3. Install XDebugXDebug is the de facto standard PHP debugger, and for several good reasons too. The more you get used to it, the more its absence on other people's machines will frustrate you . The most "basic" thing that XDebug is worth getting for is that it makes the output for var_dump() colorful (using HTML with CSS styles...), which may sound like just a cosmetic fluff, but if you're var_dump()-ing large arrays or objects, you'll find the output is significantly easier to read. Another, more important feature, is function stack traces. What this means is that if an error occurs, you can see the exact sequence of functions that was called to produce the error, starting with one in the file that execution started at. Combined with a var_dump() of the input data (starting with the last called function, and going back one by one to the first), you can quickly find the point at which your code started to behave weirdly (and thus resulting in the error further on). There are other "fancy" features in it too, such as code coverage, line-by-line debugging and profiling, but for best experience, you need additional tools (e.g. NetBeans , PhpStorm, Eclipse PDT and Aptana Studio support line-by-line debugging after you configure them for it; KCachegrind and Webgrind can view profiling information, etc.).
  13. 3. Basic debugging techniques for some PHP codes 3.1. Problems with (MySQL) queriesUsing any SQL queries with MySQL? Write your query into a variable, and output the variable (as discussed above). There will probably be variables within the query, in which case they'll be rendered into their exact values when your code executes. Cut 'n paste the output from your "View Source" to a query line in phpMyAdmin, "MySQL Workbench" or another tool that allows you to execute queries. There you can see why MySQL is complaining about your query. (Note: The same applies to other database engines as well.) 3.2. Problems with cookies, session, redirects, caching, and moreIn addition to the stuff you see in "View Source", your browser sends HTTP headers, which your browser processes in order to determine how to deal with your content. These headers include rendering instructions (is it an image, an HTML document? Text you say... what charset?), caching instructions, redirect instructions, as well as cookies (with the session cookie being one such cookie) and more. The first step in diagnosing header related problems is seeing headers, which is not something you normally do. Depending on your browser, there are different ways of doing that. Opera: Press Ctrl + Shift + I, and click on the "Network" tab. Any new HTTP requests your browser makes will be made available there, with the request and response headers being visible by clicking once on the HTTP request you're interested in. Safari: Press Ctrl + Alt + i, and click on the "Network" tab. Any new HTTP requests your browser makes will be made available there, with the request and response headers being visible by clicking once on the HTTP request you're interested in, and clicking on the "Headers" tab. Chrome: Press F12, and click on the "Network" tab. Any new HTTP requests your browser makes will be made available there, with the request and response headers being visible by clicking once on the HTTP request you're interested in, and clicking on the "Headers" tab. Firefox: Firefox has no "built in" way of letting you view headers, but there are a few good add-ons for that, the most popular of which is Firebug. Using Firebug to inspect headers is similar as with other browsers - Press F12, click the "Network" tab, and click "Enable" if prompted. Any new HTTP requests your browser makes will be made available within that tab, with the request and response headers being visible by clicking once on the HTTP request you're interested in. IE9 and above: press the F12 key, click the "Network" tab, and click the "Start capturing" button. Any new HTTP requests your browser makes will be made available there, with the request and response headers being visible by double clicking on the HTTP request you're interested in. IE6 and above: IE8 and below have no "built in" way of viewing headers, but there are a few good add-ons for that, the most popular of which is Fiddler. This add-on can in fact also be used to inspect HTTP traffic from IE9 and Firefox as well. To use it, open up Fiddler, start browsing to the page, and you'll see the HTTP requests on the left. Click the one you're interested in, and you'll see details about it on the right. If you want your mind blown, check out the "Raw" tab. 3.3. Problems with mail()The mail() function does NOT in it of itself send an email, which is often the cause of many headaches when getting it to work properly on your own server. Just keep that in mind: The mail() function does not send emails. Instead, it asks a separate program (an SMTP server) to send an email.For UNIX (e.g. Linux or MAC), PHP has native support for "sendmail". Just like any other SMTP server or any OS, "sendmail" usually needs to be downloaded and installed separately. After you do that, you may have to open your php.ini, and set the sendmail_path directive to the path where sendmail is installed, and add the arguments too.For Windows, any SMTP server will do the trick, though you'll be contacting it over TCP/IP (you know, like with MySQL). You can specify the IP or domain name the program is running on with the SMTP directive, and the port this program is running on with the smtp_port directive. The default values for these are set to "localhost" and "25", respectively, so if you just install an SMTP server on your server, there's nothing else to configure.Some examples of SMTP servers for Windows include hMailServer, Pegasus Mail, Microsoft Exchange Server, the built in SMTP server (on Windows Server), and a bunch of others.In general, using the mail() function directly is a bad idea for a number of reasons, the most important being that everything is very "raw", which in turn opens the door for a number of security issues. Consider using a wrapper library like Zend_Mail, Swift Mailer or PEAR_Mail. In addition to preventing such security issues, they also make it easy to supply additional data to the SMTP server, such as credentials, SSL encryption and more.If you have other mail related problems (e.g. messages go to recipients' SPAM folder), chances are that something else needs to be configured at the SMTP server and/or you need to supply "correct" data to your SMTP server. For example, if you want to send an email from a GMail address to someone else, you'll have to do that through GMail's SMTP server, not your own SMTP server, and login to the SMTP server with the credentials for the email the message is from.To find out exactly what's wrong, enable logging at your SMTP server, and check the logs to see the full "conversation" between it and PHP. In addition, if your mail client allows it (GMail's site allows it), check out the received message in its "raw" form, to check out the mail headers the message ended up with. Those headers are similar to HTTP headers, and in addition to telling how the message is to be handled, they also contain data like a list of SMTP servers that were in contact with the message (starting at your SMTP server, and ending at the SMTP server of the recipient's provider). Any of those servers may add/alter/remove additional headers that you may have to deal with somehow (e.g. by adding/altering/removing some headers at your own SMTP server).
  14. 2. Basic debugging techniques for any PHP code 2.1. Ensure PHP is really runningStart out with "Hello world!." Here it is: <?php echo "Hello world!"; ?> Upload it to your server and see it in your browser before you proceed. You won't be doing any debugging until you have basic connectivity established. Maybe you named your index file index.php.html ... There's no point in writing 200 lines of code to discover this. This one line will let you know you have a problem and you don't need the other 199 lines of code. 2.2. "View Source" is not just your friend, but your BEST friendYou read this everywhere over and over again, and yet it can't be emphasized enough - PHP is not processed by your browser! Instead PHP generates content that your browser then processes. Whenever you see PHP produce something unexpected, the first thing you should do is to right click on the browser screen, and click "View Source" (or the equivalent in your browser; something with "Source" or "Code" in it). Your browser will open up a new window, and what you see there is the real PHP output. Whenever we talk about "output" further on, that output is the only thing we're interested in. 2.3. Find the branchDoes your PHP code have branching (if, switch, while, for...)? Put in debug statements. When your server is 3 timezones away you have no idea if any particular code executed. A simple echo "Hi!"; will tell you execution got to a particular statement or line. If you see "Hi!" in the output, then PHP got there, otherwise not. This is just an extension of the "Hello world!" concept. Simply add something akin to the above within the branch you want to make sure was executed. 2.4. Dump variablesRegardless of whether you're dealing with a string, a number, or even an array, you can use var_dump($var); where $var is the name of a variable you want to output (notice there's no "echo" here). This will tell you the value of that variable, as well as its type. For strings, var_dump() would also tell you their length, and for arrays, it will also tell you the type and value of each array key and value. If you want to avoid disrupting the browser rendering, you can place the var_dump() output within an HTML comment, like: echo '<!--';var_dump($var);echo '-->'; Don't want to put it in your HTML or comments? Or is there a problem with doing that? You can write to a file instead. Just choose a name for a file (whatever you want... let's say "debug.txt" for example), and make your PHP code write the values you're interested in it, like: file_put_contents('debug.txt', print_r($var, true)); You'll notice the print_r() function. Similarly to var_dump(), that outputs information about a variable, although it tells you less things about arrays and strings (no types, no lengths). 2.5. Decode the error messagesMost of the time, the problem stares you in the face, in the form of an error message. The messages often sound cryptic, but if you look closely at the details they provide you with, you can often find and fix the problem. In particular, look at the file and line provided. See what's there. See what's required for that line to execute properly. Try to create a new file (just to test this one behaviour) with just this line and its requirements (a.k.a. "input"), and see if you get the same error. - If you do get the same error, ask yourself what's wrong with the input. Is there any other way you can express that input (e.g. if it's a URL, can you use an absolute instead of a relative one; if it's a number, must you be in a certain range, etc.)? What is expected to happen with that input? If this is not your own function, look at the relevant documentation for clues. - If you don't get an error, ask yourself what is different, and look for clues in the text of the message itself. Slowly, keep copying more of the "real" code into the test file, until you can reproduce the original error. If after hitting that point you can't figure out what's wrong, you're in a good position to create a topic in the forum, with the test code provided in it, along with details on the turning point.
  15. You can't change existing hashes into a new one.Your users would have to create new passwords (which could be the same as their old passwords), which would in turn generate new hashes for you to then check.As for how to do hashing with SHA-512, see crypt().
  16. boen_robot

    debugging isuues

    You only need one. The other commented ones are just usage examples. Set it like display_errors = On just in case.Another thing may be influencing things is the error_reporting directive, which determines which errors are reported. Find it, and change it to error_reporting = E_ALL (I would've said "E_ALL | E_STRICT", but PHP 5.4 includes E_STRICT in E_ALL)
  17. Because if the body is just one statement, adding the braces is optional, so the author took advantage of that to make the code feel cool. I'm all for code that feels cool, but IMHO, a beginners' book should explicitly clarify any "cool" stuff used, and in fact, it should absolutely avoid using cool stuff, with the exception of a special chapter dedicated to that.Other "cool" constructs you might occasionally find are (just to give you some terms to chew on ) object invokes, self returning mutable objects (think jQuery), hex/octal number notations and include returns. Yes, the assignment operator assigns the value on the right to the variable on the left. But the returned value of the assignment operator is the assigned value.So, whether you havewhile($row = $result->fetchObject()) or just while($result->fetchObject()) The loop will still be executed the same number of times.The difference is that with the second variant, you have no way of reading the data returned from fetchObject(), since the returned object is discarded after the check. With the first variant, the returned value from the assignment operator is discarded, but a copy of fetchObject()'s returned value is still in the $row variable. the names $k and $v are arbitrary. They can be anything you want, as long as you keep using those same names within the foreach.This form was used so that within the foreach, you can read the exact array key ($k) associated with the value ($v), which is needed in this case.
  18. Maybe class init { static function load_script() { global $var;//Add other variables you wish to export to the global scope require_once('file1.php'); }} But better yet... why don't you ditch global variables in favor of static properties in the class?So that your class is something like: class init { static $var; static function load_script() { self::$var = 'something'; }} And in file3.php, you do include('file2.php');init::load_script();//Later, when you'd previously be using $varecho init::$var;
  19. There's no need to suppress that habit.Just add the additional habit of adding braces to every control structure, e.g. while($row = $result->fetchObject()) { $artists[$row->artist_id] = $row->artist_name; }
  20. boen_robot

    debugging isuues

    Yeah, sorry. I meant without NetBeans' "debug" feature (which in turn uses XDebug's debugging capability; hence I can't tell if this is NetBeans' fault or XDebug debugger's fault). You set "display_errors" to "On" in php.ini, or use ini_set() within the file for the same setting (though, obviously, the fatal error in question would have to happen no earlier than that point in the code). If you enable it in php.ini, all errors defined by the "error_reporting" php.ini directive will be written into that log. This includes parsing errors and fatal errors.
  21. boen_robot

    debugging isuues

    This happens on fatal errors. The moment that NetBeans starts doing that is the moment the fatal error has occurred. To find out the exact error, you'd have to either run the page without XDebug, seeing the message and/or enable error logging and look at the logs after the run.I'm not entirely sure if this behaviour counts as a NetBeans bug or an XDebug bug.Anyway, in some scenarios, it's easy to guess the fatal error even without seeing any messages. Calling an unidentified function is a fatal error, so if NetBeans hangs like that at if(!filled_out($POST)) Then chances are that filled_out() is not a defined function (maybe you missed requiring the file its in?). Similarly, being unable to locate and execute a required file is a fatal error, so if the hang is instead at require_once 'userauth_admin.php'; then 'userauth_admin.php' is missing/mistyped, or PHP doesn't have enough permissions to access it.
  22. Turn error display on, i.e. add ini_set('display_errors', 'On');error_reporting(E_ALL | E_STRICT); At the top of your PHP file. Chances are that there'll be some sort of message telling you why it doesn't work.
  23. Look closely at those two lines: while($row = $result->fetchObject()); $artists[$row->artist_id] = $row->artist_name; If you look close enough, you'll notice the second line is NOT part of the loop. while($row = $result->fetchObject()) declares a loop, and the very next symbol, ; ends the one statement that would then become the loop's body.But the loop ends when $rows becomes false, due to fetchObject() returning false when there are no more rows. So by the time the next line executes, $row is not an object => you get this error.The same applies to while($row = $result->fetch(PDO::FETCH_OBJ)); $ratings[$row->rating_id] = $row->rating_name; as well.
  24. Wait, are you trying to paginate SQL data? There's a much easier way than what you're doing: Use LIMIT (see SELECT in the MySQL manual for details).The first number in LIMIT is the starting point, which is easily calculated by multiplying the records per page with the page number (-1, since the first page will need to have 0 as this first number). The second number is the number of entries past the offset, which is basically equal to your records per page.Not only is this more efficient, it's also easier to deal with, as once you take the result set, you just output it in the same fashion as you'd output it if there was no pagination.
  25. The copyright applies if you publish that reference.If you just generate it yourself by whatever means, and keep it to yourself, there's no problem.
×
×
  • Create New...