A real gem from the same comment thread:
> […] you use PHP to perform MySQL queries in the middle of HTML tags. If you want to do this, you know some principles are merely burden for your smooth execution of the web site development, and should be throw out the window at first thought.
Just a few off the top of my head:
But yeah, PHP7 is basically a version that is making great strides to fix what was broken with PHP.
> I was really, really bad at writing parsers. I still am really bad at writing parsers.
-- Rasmus Lerdorf
> I'm not a real programmer. I throw together things until it works then I move on. The real programmers will say "Yeah it works but you're leaking memory everywhere. Perhaps we should fix that." I’ll just restart Apache every 10 requests.
-- Rasmus Lerdorf
> A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08").
This is actually false! The documentation lies. Numeric keys that fit inside an integer (or is it float?) on the current architecture will be cast to integers. But longer strings will not, as I describe in a recent thread.
Not only that, but creating an array with integer literals behaves differently than creating one with string literals.
$number_key_array = array( 12345 => "Foo", 123451234512345 => "Bar", 123451234512345123451234512345 => "Baz" ); var_dump($number_key_array);
$string_key_array = array( "12345" => "Foo", "123451234512345" => "Bar", "123451234512345123451234512345" => "Baz" ); var_dump($string_key_array);
Results in this output:
array(2) { [12345]=> string(3) "Foo" [-2147483648]=> string(3) "Baz" } array(3) { [12345]=> string(3) "Foo" ["123451234512345"]=> string(3) "Bar" ["123451234512345123451234512345"]=> string(3) "Baz" }
Two big "what the fuck"s there:
First that using any large integer literal as a key casts the key to INT_MIN
.
Second that explicitly specifying string keys casts only some of them to integers.
It may be stupid, but it's documented. (unset) $var does not do anything. It just returns NULL. The idea of casting a value to null is insane as well.
Note: PHP has always had variadic functions, this is just a more convenient and clear way to implement them.
The only thing this adds which was not possible previously, are by-ref variadics for userland functions.
/g
modifier to regex, get an array of matches back, maybe multidimensional if you used subgroups. You can figure out how to count arrays, right? OK, we cool.$matches
variable it'll throw up an error.what the actual fuck
Bonus DLC: The <code>//e</code> modifier's description is even more incredible.
No, the lolphp is that escapeshellcmd()
exists at all. Most other languages don't have such a function. It's needed in PHP because there is a <code>system()</code>, but there is no <code>exec()</code>-like family of functions where you can pass the command-line arguments as an array.
escapeshellcmd()
is a doomed strategy anyway: how can you be sure that you've escaped all characters correctly for all kinds of shells in existence?
They could make that more clear by not hosting the documentation.
As a side note, arrays, classes, and other functions are also listed as extensions in the documentation.
> PHP has no portable way to run an external command without a shell
I didn't believe you.
I checked.
Out of 6 builtin functions to execute external commands (exec(), shell_exec(), passthru(), system(), proc_open() and popen()), 6 spawn a shell, that's a downright impressive level of suck. Apparently the only way to not spawn a shell is to use PNCTL which may not be installed and seems to only be available in PHP/CLI.
> They could make that more clear by not hosting the documentation.
Yeah, that's a kind of a historical mistake: for some reason, the official PHP documentation includes documentation for a bunch of PECL extensions which aren't distributed with PHP, and which aren't developed by PHP core developers. I don't claim to understand it, but I'm sure they have their reasons. :/
This page lists the extensions (and "extensions") in a clearer fashion.
It kinda looks like you tried to "type hint" to class string
, attempting to hint the scalar type string - available in PHP7. Is that what happened here?
Assuming you saw this in the docs - http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration
Are you using PHP7?
Tozawa et al. (POPL '09, 200-212) did some fairly extensive research on precisely this problem. They introduce a "mostly copy-on-write" scheme to avoid the problem.
You can find a PDF here: https://www.researchgate.net/profile/Yasuhiko_Minamide/publication/220997065_Copy-on-write_in_the_PHP_language/links/0fcfd5101e81b8a0c2000000.pdf
> This should return false.
That is not true. According to the documentation for empty
:
> No warning is generated if the variable does not exist. That means empty() is essentially the concise equivalent to !isset($var) || $var == false.
Notice that last line? ... || $var == false
. If it were $var === false
, you would be correct. But an integer 0
or a string '0'
both == false
.
Example: http://ideone.com/WUbVSE
Edit: I'm not saying that '0' == FALSE
isn't lolphp enough on its own, just pointing out that the documentation clearly says ==
not ===
.
That's probably why the documentation says "This function does not generate cryptographically secure values, and should not be used for cryptographic purposes."
I think you're confused. It's okay; PHP is a wart-ridden language, so it's easy to become confused.
According to the right fine manual, int
, integer
, bool
, boolean
, float
, double
, real
, string
, array
, object
and unset
(lol) are all reserved keywords, at least inside parenthesis where they're used as typecasts.
I don't know if the fact that SimpleXMLElement is a documented special case makes it more or less perplexing.
(If it makes you feel any better, that StdClass would have been fasley in PHP 4, which would have been... more consistent? less consistent? less nonsensical? none of the above? I don't know.)
No. In PHP, if a function returns void, you should expect var_dump to output NULL
. unset()
is not a function, it's a special case in the grammar. One of many, many special cases in the grammar.
Here's the first actual function I could find that is documented to return void, if you want to try it.
> you cannot just break it from one version to another without much care.
Yeah, but that still happens. Case in point.
Wrong behavior fixed, don't tell anyone. I mean, at all. There's no documentation for this change anywhere that I can find. Not even in the 5.4 to 5.5 Backwards Incompatibility change log.
The canonical example is things like common cleanup, particularly with nested loops or other complex iteration; this is common in the Linux kernel, which you can read.
<initialization 1> for (i = ...) for (j = ...) ... if error or done goto cleanup1;
<initialization 2> for (... while if error or done goto cleanup2
cleanup2: <clean up anything left from initialization 2> cleanup1: <clean up anything left from initialization 1> return
Kernel coding style: see "Chapter 7"
The fact that this can be mathematically transformed into some other form is completely irrelevant and not actually an argument against it. Every program can be mathematically transformed into a single while loop, but we would never write a program that way because we would not be able to do it correctly.
The "structured" alternative of "maintain boolean 'early exit' flags and check them everywhere" is more error-prone and hard to read and maintain.
If you want to see what Dijkstra was complaining about, find some old Fortran 77 code designed for good numerical performance over a wide range of inputs, and you'll go crazy trying to follow the gotos.
The one from Debian is pretty good IMO. You can read just the 6 bullet points, and you'll know enough to follow the rules, but if you want clarification, there's a short paragraph explaining the spirit of each. It strikes a sweet spot between "too verbose" and "too vague" IMO. More importantly though, it words things positively, explicitely allows (and even encourages) disagreement, and touches on diversity without making a big fuss about it.
>What's surprising is that many people think + should concatenate strings.
I agree, it's surprising. That's not what I thought it would do. It should throw an error. Anything but continuing with wrong data.
>It could possibly just be invalid syntax, but php has a feature that strings in a + operation are coerced to ints.
While weird I can live with that (if need be).
>That makes sense in a web world where integer data is often represented by strings (json etc) e.g. "2".
In json, integers exist ( http://www.tutorialspoint.com/json/json_data_types.htm ). Whether they are used or not depends on the person, I guess.
But you probably meant HTML attributes and there, I agree (and I think that's silly of HTML). Even then, explicit conversion at the input gatekeeper is better than doing it everywhere.
>Again, php could stop,
Yes, and it should (throw an exception).
>but instead it just omits them.
Silent data loss.
>As long as it's a choice that is backed with sound arguments and well-documented I don't think it's that stupid.
I think it's ... gross negligence to silently lose data.
>What's stupid is using + on two strings that you know don't just contain numbers and then acting as if it's the language's fault.
It's the language's fault that it does not complain.
It's just different design and I guess for a HTML templating language it's acceptable that it does that (if it's fine with me not ever using it). If people would just not use it for anything else (like any validation or, worse, writing to a database).
But design can be bad. And that design is bad.
Funny enough, the documentation (http://php.net/manual/de/class.datetime.php) does not have a single example for timezones not being a "random letter".
const string ATOM = "Y-m-d\TH:i:sP" ; const string COOKIE = "l, d-M-Y H:i:s T" ; const string ISO8601 = "Y-m-d\TH:i:sO" ; const string RFC822 = "D, d M y H:i:s O" ; const string RFC850 = "l, d-M-y H:i:s T" ; const string RFC1036 = "D, d M y H:i:s O" ; const string RFC1123 = "D, d M Y H:i:s O" ; const string RFC2822 = "D, d M Y H:i:s O" ; const string RFC3339 = "Y-m-d\TH:i:sP" ; const string RSS = "D, d M Y H:i:s O" ; const string W3C = "Y-m-d\TH:i:sP" ;
I didn't even know these letter-encoding existed.
Don't use floats to represent currency values.
Don't use floats to represent currency values.
This behavior isn't PHP-specific. It has to do with some values being unrepresentable in IEEE floating point. Python has the same problem, for instance.
Yes:
>When the garbage collector is turned on, the cycle-finding algorithm as described above is executed whenever the root buffer runs full. The root buffer has a fixed size of 10,000 possible roots (although you can alter this by changing the GC_ROOT_BUFFER_MAX_ENTRIES constant in Zend/zend_gc.c in the PHP source code, and re-compiling PHP). When the garbage collector is turned off, the cycle-finding algorithm will never run. However, possible roots will always be recorded in the root buffer, no matter whether the garbage collection mechanism has been activated with this configuration setting.
>If the root buffer becomes full with possible roots while the garbage collection mechanism is turned off, further possible roots will simply not be recorded. Those possible roots that are not recorded will never be analyzed by the algorithm. If they were part of a circular reference cycle, they would never be cleaned up and would create a memory leak.
From http://php.net/manual/en/features.gc.collecting-cycles.php
So if you disable GC, make a shitload of objects in the hot spot of your code, and then enable GC again to clean it up, you risk having a memory leak.
What is the point of having a function to randomly generate numbers if you can't count on it to randomly generate numbers correctly? I don't get how you can act like someone is an idiot for using a function for the purpose it was clearly created for and is advertised for in the docs.
http://php.net/manual/en/function.mt-rand.php
This does not list any reason why you should not use this function unless you need a cryptographically secure rng which OP did not seem to need.
This function is the first result when I google "php random number" and second result if I google "php rng".
Should I go read an article on every method in php I want to use incase there is some edge case where it just completely fails? That's stupidly unrealistic.
Just because you are accustom to swimming in filth doesn't mean people want to jump in with you.
I understand that. The problem is that you have a number of start-tokens matching another number of end-tokens. So:
<?, <?php and <script language="php">
all match:
?> and </script>
And that's just evil. Here is a slightly similar though worse example posted a while ago to this subreddit.
Because array_unique converts everything to strings to sort it.
Obviously you need to use the SORT_REGULAR flag which is, logically, not the default option.
EDIT: I also just realized that in PHP 5.2.9 SORT_REGULAR was in fact the default value (that version is when the flag was introduced). Apparently it got changed to SORT_STRING in the next version (most likely because of some backwards incompatibility).
The "-" is not part of the integer literal, it is an operator applied to the integer. And that integer already overflows the integral range, becoming a float. The same problem exists in C and C++.
To be fair, it does!* http://php.net/manual/en/function.strcmp.php#113364
Also I decided to see how hard it is to write a strcmp() in PHP. Turns out it's remarkably easy!
All you have to do is use the old shell programming trick to check if a variable is empty. PHP can handle the rest!
I know it's easy to hate on PHP, but since it's a dynamic language this is just type juggling.
Using a static type language this code would be invalid as $data
couldn't be a string and an array at the same time and would have to be declared as either or. In C there is no string type, there is char which can be used to create a string from an array of characters, this is where PHP is getting the array for the string from. You can reference each letter from the string using it's index so $data[0]
is u
, $data[1]
is s
etc, since PHP doesn't expect you to reference a char array using a key like confirmed
it throws a warning and spits out $data[0]
which is u
in this case.
If variables are going to be reused like your code above, then logic would say you should at least check that $data
is the type expected before using it in a condition, otherwise don't reuse variable names across different data types.
if (is_array($data) && isset($data['confirmed']) { echo "Brilliant success!"; }
I was laughing, then I was crying.. because I knew Rasmus wasn't kidding. Somebody really needs to point that guy at Uncle Bob's "The Clean Coder." I mean, wtf, the first rule is "don't break working code" ... you just don't... wtf.
>In many languages you can do computations with characters, because they are just numbers interpreted as characters. Perfectly fine. The stupid thing is that PHP seems to do computations on actual strings
You're showing a lack of understanding of PHP rather than indicting PHP itself.
PHP doesn't have a character type. A single character is a string just like two or three etc. characters are.
With that understood, why would you expect operations on a string with a length of one to behave specially? If you want to perform operations on a character use <code>ord</code> and <code>chr</code>, but those don't work with all of Unicode since UTF-8 can represent since "characters" as multiple code units (i.e. bytes).
So basically if you're performing operations on individual characters you should probably rethink what you're doing rather than critiquing PHP. Odds are what you're doing is terribly broken.
Link to the docs with all the possible casts:
> > Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool voodoo, but still voodoo. > > -- Brian Moore > >
That's from apache's official documentation on mod_rewrite
.
No, it is in the doc. I just went and found it. Scroll down and look what it says when operand 1 is an array and operand 2 is anything else.
http://php.net/manual/en/language.operators.comparison.php
I think your case probably turns out that way because objects are also always greater when they aren't compared to other objects. Having two types that are always greater doesn't work as advertised when you compare those two different types.
> Or you can check the output with is_nan(), === INF and === -INF…
I’m pretty sure those are the funny values /u/cbraga is talking about. Bit of a pain in the ass to have to follow up your arithmetic with if (is_nan($val) || $val === INF || $val === -INF)
all the time, don’t you think?
Apparently, though, there is now an intdiv function that you can use. I was unaware of that until it was mentioned by /u/nikic above. Guess unless your code and is set up to handle those funny values, you just got to get used to doing your division with that rather than /
.
Oof that's a funny one. It looks like you can call the function, you just have to be careful not to accidentally use the syntax for invoking a method which takes priority.
https://repl.it/repls/TriflingThunderousBackend
This gives me an idea for another funny lolphp, in which you can call an integer as a function:
> If the optional raw_output is set to TRUE, then the md5 digest is instead returned in raw binary format with a length of 16.
And on the same page, the example uses === for string comparison
Oh, I see.. I think the reason for that is that escaping does prevent string interpolation (think "{\$var}"), but \{ isn't a valid escape character like \$, so both characters are printed (e.g. "\z" would print both characters). Only the inner part is being evaluated there.
That does look confusing, because the 'fake' escape characters can affect interpolation.
fwiw, it does appear to be documented.
This is great, so many strawmans.
> Just look at his list of "surprises": mysql_real_escape_string? OH MY GOD! SHOCKING! What the hell is he talking about?
Maybe this http://php.net/manual/en/function.mysql-escape-string.php ? I mean, I would be surprised to browse any API and see a "foo", and then finding elsewhere "real_foo". There's is zero way to discern the semantics of these things, without reading the manual entry for both functions.
> PHP takes vast amounts of inspiration from other languages, yet still manages to be incomprehensible to anyone who knows those languages.
to which he rebuts
> That's the point of making new languages.
Like someone else said, you can't make this shit up.
Edit: The author of the "a fractal of bad design" also posts in the thread:
> D+, see me after class.
The real WTF is that the first way works. The docs has a rather explicit note about the order in which classes must be declared (Emphasis mine).
> Unless autoloading is used, then classes must be defined before they are used. If a class extends another, then the parent class must be declared before the child class structure. This rule applies to classes that inherit other classes and interfaces.
PHP defines how strings and numbers compare to each other with all of their comparison operators. For better or worse, they've decided that 4 < "25"
is a sensible comparison in the language (evaluates to true
).
Now there's lots of evidence to suggest that this was a bad idea from the beginning, that allowing strings to be compared as though they were numeric values is a lolphp all on its own. I assume the reason they did this is so that you can do things like if ($_GET["num_fields"] > 4)
without converting HTML form values to numbers.
But given that numbers and strings can be compared in PHP, the fact that min
and max
will compare strings this way is pretty expected, and the functions behave exactly as I would expect given the decisions the PHP language designers made long ago.
Is this sensible? I dunno, but it's consistent: https://repl.it/repls/PointedDarkturquoiseHacks
> You can get a whole lot of work done with PHP without knowing how to install modules. You could use composer, but most new PHP developers probably won't use that, as there's already a ridiculous amount of things available by default.
Fair enough. However, it's not really that much of an advantage as learning to use npm/go get/gem/etc shouldn't take more than half an hour max.
Also - there is more than just mysqli for PHP, the docs even have a section on choosing between the <em>three</em> clients. How is that different from looking at different clients on npm (of which the right one is called 'mysql' and the rest are obviously not the right one and kinda hard to even find)?
Yes; any production server competently configured will use one if speed is a concern, and PHP 5.5 even ships with one. It's unclear whether the numbers they're comparing against for on this page are calculated using an opcode cache or no, but I'm guessing not.
The linked code runs crypt
with a $2y$
salt, which according to the <code>crypt</code> docs:
> CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$" > > … > > Caution: Using the CRYPT_BLOWFISH algorithm, will result in the str parameter being truncated to a maximum length of 72 characters.
And the reason is, "documented behavior"!
"Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same." http://php.net/manual/en/function.array-intersect.php
From the manual page comments, why is the comment from "mchljnk at NOSPAM dot gmail dot com" rated at -2? I would think this bit of knowledge might be important. While the doc does say it fills the new array with the value you pass in (in this case, a single new "Foo" object identifier), this behavior regarding objects might be something worth mentioning at least since it might be easy to get caught offguard because of it.
class Foo { public $bar = "banana"; }
$array = array_fill(0, 10, new Foo());
echo $array[0]->bar . "\r\n"; // "banana" $array[0]->bar = "crap"; echo $array[9]->bar . "\r\n"; // "crap"
Only if you're in a situation where you can't use /dev/urandom (or CryptGenRandom on windows) is not available openssl_random_pseudo_bytes really isn't any better. See http://www.openbsd.org/papers/bsdcan14-libressl/mgp00017.html. They may end up using a constant string in the source code as an entropy source. Crashing on there inavailability is a good option.
In my opinion, the only way it would get better is if the whole thing was scrapped and redone from scratch. The end result, if it was good, would not be backward compatible and wouldn't be "PHP" anymore. Hack is doing something, but I don't think it's enough. Probably because they (at Facebook) need to stay compatible with PHP as they transition. Just my opinion though. I guess I'm one of those "no hope for that" people, but I don't make a living writing PHP code either.
> I'm sure someone somewhere is using eval for something important
Here's one widely used scenario: Yii Framework has this <code>evaluateExpression</code> method and uses it everywhere, for example, when you want to display objects: http://www.yiiframework.com/doc/api/1.1/CGridView . Every tutorial, official or not, demonstrates the string/eval version and forgets the callback/anonymous function version.
At least in Drupal, it's explicitly recommended not to do this on the coding standards page, since short tags can be turned off with a PHP config flag, whereas <?php
always works.
Really wish more people would read that page.
Javascript doesn't convert strings to ints like PHP, it converts the int to a string because + is also string concatenation in js: http://jsfiddle.net/pvme9gh6/
The advantage is that no data is thrown away.
It is not. This is neither first nor last implementation of DNS resolver in PHP; this one at least looks decent, code-wise.
Oh, that's cool!
brb, gotta replace opensshd with that slick SSH server written in PHP!
Yep, 0 == false
is in general perfectly reasonable; I've no problem with it in C and Python. It's included in that expression because it demonstrates that PHP's equality isn't transitive, i.e., a == b && b == c && a != c
, which is ridiculous.
It's worth mentioning however that the equivalence 0 == false
does cause a problem in PHP, all by itself. strpos() and related functions return "the index of the match, or false
if nothing is found". Of course, 0 can be the index of a valid match, but 0 == false
, which indicates no-match-found. Not cool.
JavaScript's indexOf()
, which is essentially equivalent to strpos()
, returns -1 on no-match-found, which doesn't actually compare equal to any "successful" return value even if you aren't using ===
and therefore would've been a much more sensible choice. C's strchr()
and friends return a valid pointer to the location found, or NULL
on no-match-found, which also can't compare equal to valid matches.
I appreciate the reply and I actually agree with that, I myself prefer strongly typed languages.
But I miss the days when people actually studied things and not just made assumptions and/or express entitlement about how something should work. Weak typing is a thing, a very widespread and well known/documented thing.
It's a HERE BE DRAGONS when it comes to mixing types with each others and is called weakly typed to be explicit about the fact that programmers need to take heed when doing it.
To expand on the original post/this entire subject (and my first comment) I don't find it at all LOL-worthy when it's a result of not bothering to read the manual pages of the primitives of a language one is using. I wouldn't presume to know how Java strings work without reading up on it.
It's annoying that the documentation that covers this seems to really only be in password_hash
, which functions as a wrapper for crypt
.
>Caution > >Using the PASSWORD_BCRYPT for the algo parameter, will result in the password parameter being truncated to a maximum length of 72 characters.
http://php.net/manual/en/function.password-hash.php
Looking at the link again, it looks like there was a second issue that I missed not scrolling down in the output. php doesn't care much about null \0
characters in the middle of a string, but the bcrypt implementation truncates the password at them.
https://www.reddit.com/r/netsec/comments/2yugos/null_bytes_bcrypt_problem/cpd9yvi
edit: missed the below note when skimming this last night, thanks!
You may not know about the bug. Context is a reality, as you say.
Anyway, I'm done, you're a dick. I can't figure out if you're intentionally being a dick or if you're just an asshole. Leaning towards the latter.
Parting remark: There is polymorphism, and then there is PHP: http://php.net/manual/en/types.comparisons.php
I actually tried doing this for an import framework I wrote and tweaked the batch size back and forth. The golden number is 300 batch rows, after that the query starts slowing down again. I never bothered to write it down with multiple measurements though. And who knows, maybe ministat would have told me to fuck off and go do something more productive if I entered the data.
try looking at http://www.sinatrarb.com/ then for a lightweight ruby framework. ruby is easy to write and understand, i can recommend it for small web apps.
nodejs or python would be my #2 choice, or maybe golang too if you like a C-style language.
nodejs isn't bad, i don't get why a lot of people seem to hate it. add some http://coffeescript.org/ and it's superb.
Or you've got Go, where the official statement is something along the lines of
> A ternary operator is at best as clear as an if statement, and is never, ever necessary. Therefore, Go doesn't have it.
Problem solved.
You shouldn't trust C implementations as reference
http://www.postgresql.org/docs/9.2/static/protocol-overview.html#PROTOCOL-FORMAT-CODES
My Postgres driver in Limbo uses the type information.
No examples since you can view just about any file there and have a pretty high WTF/min rate. But seriously speaking, it's just lacking any architecture or isolation/abstraction of routines. Models are some variables here and there, views and controllers are mixed together, and html structure is a bunch of echo strings - maybe I was blind but I was unable to find any template files in that repo. SQL queries everywhere, decentralized. Using global variables inside functions (instead of bringing them via parameters) is bad practise. Repeating routines. You could read the whole codebase as a counter-example to what Steve McConnell tries to tell you in Code Complete.
I guess the owners just wanted quick and dirty prototype code that could be sold to its clients before coming back to improve the architecture. The company's revenue was 763 000 € in 2011-2012 with diminishing profits at around 11k (with last year's profit at 23k). [1] I'd really like to know how a business is able to spend almost 800k with a crew of 10.
>it's a compiler error in Haskell to have an infinite loop
No it's not. This code compiles fine and hangs at runtime:
f :: Int -> Int f = f
main = print (f 1)
The main issue here, for me, are the shenanigans with typing. NULL == FALSE == 0. So, an empty variable is NULL, FALSE, 0, and non-existent at the same time. Which is it?
And why the fuck an non-existent variable can be empty?! It doesn't exists, and can't be anything! Also, isset doesn't consider a null variable as set (so, does it exists or not?). But wait! If that variable is false, it will be considered set. However, null is equal to false... So which one is it?
The triple = BS is really tiring.
Honestly array_unique
acts about as reasonably as can be expected given PHP's bizarre ==
operator.
<?php
var_dump('' == 0); # bool(true) var_dump('lolphp' == 0); # bool(true) var_dump('' == 'lolphp'); # bool(false)
https://repl.it/repls/DescriptiveGlassDatasets
If you want a real dose of WTF, try this:
<?php
echo json_encode(array_unique(array(0, 'lolphp', ''), SORT_REGULAR))."\n"; # [0] echo json_encode(array_unique(array('lolphp', 0, ''), SORT_REGULAR))."\n"; # {"0":"lolphp","2":""} echo json_encode(array_unique(array('', 'lolphp', 0), SORT_REGULAR))."\n"; # ["", "lolphp"]
Sounds like something that should be reported to PhpStorm. I notice that the PHP syntax highlighter for https://repl.it also thinks that <?php}
is a valid PHP opening tag when it isn't (though it uses a proper PHP interpreter so when you run it it does the right thing).
No. This has nothing to do with JSON. This has all to do with how poor the PHP array design is. The culprit is how bad array_filter really does its thing.
Heres a sample of what you must do as a PHP user to actually get what you wanted in the first place.
The best way to clean up an array in PHP in order to get the elements by their position is using array_values( [4 => 'b', 0 => 'a'] )
this will return array(2) { [0]=> string(1) "b" [1]=> string(1) "a" }
​
I'm not saying this is great, but at least you have the tools to get the things done if you need to work with this language. https://repl.it/repls/BlaringAggravatingPipelining
​
The same applies to the example: $lol2 = ['a' => 'list', 'of' => 'keyvals'];
next $lol2 = array_values( $lol2 );
var_dump( $lol2[0], $lol2[1] );
returns string(4) "list" string(7) "keyvals"
Other than for ease of use / formatting of code, the main difference is that switch is evaluated only once and the result is compared to each case statement.
$a = 1;
switch (++$a)
{
case (1): echo 'One'; break; // False, $a is 2
case (2): echo 'Two'; break; // True, $a is 2
case (3): echo 'Three'; break; // False, $a is 2
}
// Expect: 'Two'
// Result: 'Two'
Simply replacing switch doesn't work, as (in this case) the additional evaluations result in a null value:
$a = 1; if (++$a === 1) { echo 'One'; } // False, $a is 2 elseif (++$a === 2) { echo 'Two'; } // False, $a is 3 elseif (++$a === 3) { echo 'Three'; }// False, $a is 4 // Expect: 'Two'; // Result: null;
A working replacement requires assigning the original statement to another variable and then comparing that variable:
$a = 1; $b = ++$a; if ($b === 1) { echo 'One'; } // False, $a is 2 if ($b === 2) { echo 'Two'; } // True, , $a is 2 if ($b === 3) { echo 'Three'; } // False, , $a is 2 // Expect 'Two'; // Result 'Two';
There is also a fairly rare use case where you don't implement break because you want to output everything below the true case:
switch ($dwarves) { case 'Everyone': { echo ' All of the Dwarves: '; } case 'Balin': { echo 'Balin ; } case 'Thorin': { echo 'Thorin '; } case 'Gloin': { echo 'Gloin '; } case 'Gimli': { echo 'Gimli'; } } // If $dwarves is set to 'Balin', output would be 'Balin Thorin Gloin Gimli' // If $dwarves is set to 'Gloin', output would be 'Gloin Gimli'
Source: PHP: switch
Also, I noticed the documentation offers this at the top:
> Note: Note that switch/case does loose comparison.
So... the problem is documented. Ridiculous, but documented.
Which is why you should be using mt_getrandmax():
$randInt = mt_rand(1, mt_getrandmax());
mt_getrandmax() will always return 2^31 - 1, regardless of platform.
Having never used sublime's minimap, is the use case very different from something like vim's tagbar?
Edit: Also, if you want something like hasklig, take a look at yi. I suspect it might like some more developers … but it does replace <=
with ≤
, \
with λ
, ::
with ∷
and so on. Making using mouse-copying from it a real nightmare :')
This is why PHP has such a bad rep. Its a clusterfuck of badly implemented thin wrapper functions around C that dont really mix well with the rest of the "language".
Eg. heres how python handles this case: https://repl.it/repls/PoshSweetHarddrives
Simple, and predictable.
> Because I don't have to use PHP anymore, thankfully, so I don't remember its intricacies. But, aren't there like 4 levels of errors: notices, warnings, errors, fatal errors, and only fatal errors cause the script to halt execution?
No, there's notices, strict standards, deprecation notices, warnings, compile-time warnings, recoverable errors, fatal errors, and user and core variants thereof.
Recoverable and fatal errors halt execution (by default, you can make anything halt or produce an exception, except for fatals), but recoverable errors, as their name suggests, can be recovered from.
> C and C++ allow constant arrays
I didn't know that. Since there is precedent with C and C++ (PHP foundation), it actually makes sense that this PHP feature was implemented. But each array item in PHP can be of any mixed type so there is still huge potential for problems here. For example, what if one array item was an object?
> and strings, as they're just arrays
PHP has problems with freely interchanging arrays with strings. See implode as one implementation problem example: "implode() can, for historical reasons, accept its parameters in either order".
> constant arrays in PHP are immutable
Crossing my fingers that it stays that way. In a few years time, I hope this doesn't spawn a new BC argument that prevents fixing problems.
In PHP it's sometimes necessary since the return values of some functions can be either FALSE or 0. The most common example is probably strpos(). !strpos('foobar', 'foo')
will evaluate to TRUE (as will strpos('foobar', 'foo') == FALSE
), but strpos('foobar', 'foo') === FALSE
will evaluate to FALSE. I don't know how $args->rewrite is being populated in this case, but perhaps the author was exercising caution.
(And yes, I did have to just double-check the argument order for strpos() as usual.)
http://www.indeed.com/salary/PHP-Developer.html
Salary surveys are easy to find...
Apache itself has a config directive for that:
http://httpd.apache.org/docs/2.4/mod/mpm_common.html#maxconnectionsperchild
This is really a general feature that almost everyone needs from time to time. Circular refs with reference counting garbage collectors, yay!
> Other languages manage it.
You used to be able to crash Haskell programs (compiled by ghc) by doing minBound `div` (-1)
, but they fixed that a long time ago.
It doesn't really have to keep the whole scope alive, just the (usually few) variables that nested functions close over. At least that's how it is in strict mode. I believe non-strict mode makes this optimization impossible due to eval
shenanigans.
As for copying and single expressions, consider this example:
'use strict';
function make_reference(x) { return { read: () => x, write: (y) => x = y, }; }
let r = make_reference("foo");
console.log(old value: ${r.read()}
);
r.write("bar");
console.log(new value: ${r.read()}
);
It creates a reference to a value, allowing indirect modification. (Copying the reference doesn't copy the value it refers to.) It is built out of a pair of single-expression closures.
You might argue that write
is bad style, abusing the fact that assignment is an operator in JS and we should write (y) => { x = y; }
instead. Fair enough. But even so, read
is a perfectly harmless function without side effects, and yet it wouldn't work if x
were imported by value. Non-copying semantics are crucial here because we rely on the closure being able to see modifications made elsewhere. The modification doesn't have to be inside the closure.
The Javascript Object Notation is correct in assuming that you were passing a (badly formatted) integer object.
Python errors at characters 7-11 (the part that your example truncated).
http://json.org/ shows that objects start with a {, arrays, a [, and numbers (which you seem to have here) just start with digits.
What you have shown is how php deals with numbers that contain more than one decimal point.
var_dump(json_decode('"192.168.1.1"'));
That's the correct way to represent a string in php. An IP is not an integer, nor is it any other type of number. It's a string. It just so happens to consist of digits and delimiters, and we just so happened to borrow the same delimiter that numbers use.
> IMHO Go is probably better suited for web dev than systems programming
It was designed as a systems language. I'm.. just.. I dunno. I guess the conversation is over.
Actually, the relevant code is in <code>php_chunk_split</code>:
dest = safe_emalloc((int)out_len, sizeof(char), 0);
It doesn't look like it could overflow anymore. safe_emalloc
seems to be defined to avoid overflows:
void *safe_emalloc(size_t nmemb, size_t size, size_t offset)
>Allocate a buffer for holding nmemb blocks of each size bytes and an additional offset bytes. This is similar to emalloc(nmemb * size + offset) but adds a special protection against overflows.