- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
thread.php?from=1&to=1000; DROP TABLE mailing_list_table
...
Edit: http://www.devnetwork.net/forums/viewtopic.php?t=11776
Admin
no problem, mysql_query executes only first sql statement...
Admin
A friend of mine only recently explained to a colleague of his (a long-time PHP coder) how to start PHP scripts from the command line. The other guy was amazed. Until then he had triggered the daily status mails to the customers by calling a web page (I'm not kidding, this is real). He immediately set up a cron job. The result: One half of the customers gets no mail. The other half gets the same mail eight times.
Glad I'm not using PHP if only for avoiding the community.
Admin
You know, since PHP probably doesn't have a way to do multithreading (I don't have to worry about silly language limits like this since I code in ColdFusion and can always write a piece in pure Java if necessary, as CF runs on top of Java), but this seems a pretty brilliant way to do multithreading (although he probably should've used better practices to avoid sql injection, etc).
Admin
Beautiful multi-threading. If I would have known a loop creates threads by itself it would have saved me so much time! Wow this was enjoyable.
Admin
<sarcasm class="pity">GENIUS!!!</sarcasm>
Admin
Brilliant !
Portable :)
Scalable ... Without change line of code and a little DNS play or serwer setup you can gain distributed processing on multiple dislocated machines ... :)
Let's repeat ... Brilliant ;)
Just kidding ... ( really ? )
He could propose something more elegant in sense of code (AJAX request?) but this idea behind is great.
Admin
CF8 now includes the <cfthread> tag for writing multi-threaded scripts (haven't had a chance to take a look at it, but sounds interesting)
Admin
Admin
Aha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha.
Genius.
F5 anyone?
Admin
i actually think that this is a pretty clever way to do this. wouldnt say a good way, but you have to admit that it is clever.
Admin
Brillant!
Admin
Oh lovely! Side effects from a GET, just what we always needed...
Admin
Some of the comments here are bigger WTFs than the original article.
But, to be fair, I've seen code written in other languages that failed to multi-thread in an equally dismal manner. The difference is that it was written by people with many of years of experience.
Admin
Actually it does: http://ca.php.net/manual/en/function.pcntl-fork.php
Admin
Admin
The problem is that this guys thinks he know the buzzword to the solution of what he wants to do - which is not threading, but avoiding timeouts.
It's pretty common for PHP scripts that take a long time to execute to bite the task at hand into smaller chunks that can be executed quickly, and thus avoiding asking your users to edit the "max_execution_time" (or whatever it's called) setting, which isn't available in many shared hosting setups.
And the solution given isn't a WTF, it's just bad PHP quickly churned out on a forum.
Admin
There's not much wrong with the concept, other than the whole side-effects-from-a-GET thing. It uses two Web server worker threads (since that's how many Internet Explorer and Firefox would use by default) to send e-mails. Not 10, just 2. Perhaps the environment they're running in restricts the use of forking, as would happen when also running mod_mono or mod_aspdotnet or mod_cli or certain other mods.
TRWTF is that it sends e-mails to the first 1000 people 10 times, and none to any people after that (!)
Admin
Admin
For those who didn't catch the WTF, the HTTP 1.1 spec states that client programs should only make two connections to an existing server (8.1.4 Practical Considerations) so you'll only get two threads!
<wink />Admin
Technically that makes a new process, not a new thread.
Addendum (2007-08-13 10:14): Oops, this was in reply to:
Admin
It might sound wrong, but it's quite typical. A web server has multiple threads/processes to handle requests. It's not the PHP engine that's creating the threads, but the web server, and the PHP engine gets invoked from those threads. The multithreading here comes in (as has been said by others) in the fact that web browsers request multiple images at a time.
Admin
Not too worry, php doesn't do any such thing. apached does. In fact, it has a setting for how many apache instances you want to have waiting in the background just in case someone decides to connect!
Admin
hahahahahahaha... seriously now.
Admin
Admin
... ick.
I like PHP for web development but using it for this is just... wrong.
Write your emailer in some other language that supports threading or doesn't time out or... I don't know, actually was meant for applications.
The fact that you can write command line apps in PHP is the worst part of that language because it encourages people to do so. PHP is for web and should remain there.
Admin
Admin
Uhm, ugly hack as this is, it isn't even multithreading proper. The different 'threads' do not share the same variable/memory space.
Admin
Yeah, it's funny, because the person replying has only replied once on this board, and the rest of the thread is made up of intelligent responses that not only serve to educate but also try to solve the problem.
As the owner of the board, it's kinda odd you'd choose to ignore that aspect. Some guy was given some bad advice, and it was corrected.
Admin
Well, if he means "Silly language limits like not being able to use multiple threads", then he has a point. CF8 supports multithreading using Java's Thread class.
If he means "ColdFusion doesn't have silly language limits", OTOH, then, well...
Let's just say, as much as I like CF, on occasion I just want to slap the whole engineering team and ask "WTF?"
Admin
Actually it's quite useful. I converted a number of Perl scripts to run in command line PHP. If you know what you're doing it can be VERY useful. If you don't know what you're doing then you shouldn't be using it.
Admin
And everybody knows that in order for this to actually work the file MUST be called multithread.php so the server knows to start a new thread for it...
Duh.
</sarcasm>Admin
"TRWTF is that it sends e-mails to the first 1000 people 10 times, and none to any people after that (!)"
So is that why we are currently being flooded by spam these days?
Admin
Admin
On a shared webhost which is so locked down you dont have permission to do anything. If you have 1000 emails to go out and your script time is getting close to 30 seconds, sometimes not everyone would get the email. this could keep the app working.
this obviously isnt very enterprizy but i wouldnt have any problem doing this for someone who is on free hosting and wanted their mailing list to get to everyone
Admin
And that shared web host would obviously allow you to inject 1000 mails in the mail server?
Excellent way for the web host to get blacklisted.
Admin
actually, the story said the guy wanted to run a script simultaneously 10 times... while threading isnt the same as forking, you'd get the same end result.
Admin
so i dont really understand, is the wtf that php doesnt support multi-threading... being that its really just a web based scripting language(not really necessary for that anyway) or that someone wanted it to be threaded, and came up with a fairly reasonable solution(aside from using the forking extension mentioned above
Admin
Admin
Never bite the task at hand that feeds you.
Admin
Never bite the task at hand that feeds you.
Admin
I am not entirely sure why are you guys making fun of it. The point here is that he is using the web server as his threads framework. Each time he calls a page in the loop, the web server will create a thread or a fork executing thread.php, so what exactly is the problem with that code? He is just not doing it using internal language mechanisms. Oh, yes, SQL injection is bad, but threading is brilliant (I wouldn't use image tags though).
Admin
So sad; I fully understand the frustration in working in an environment where it seems like you're the only one who knows what the hell you're doing, and the only one willing to pull your own weight.
On the other hand, in this industry, there is so much to know - there's really no person who can know it all.
So, it also sucks to work in an environment where people are not willing to help bring new people up to speed. Everybody gets so territorial, and competitive, and is trying to shoot everyone else down, instead of working as a team. It really sucks. Especially when you end up maintaining someone else's code who nobody else would help, and they had to try to do the work anyway - maybe it's so bad they ended up getting fired, like you had hoped. But now, you have to fix it anyway. Would have been better if you'd helped the poor kid.
I've been on both ends of that stick, and in both kinds of work environments - and I have to say, the best environment is the one where everybody helps eachother out. It can have frustrating moments, but you're really better off in the long run. (and co-worker relationships are far better).
Admin
WTF-able from both aspects:
Thinking that "running scripts in parallel" requires "multithreading".
Thinking that in order to fork processes in PHP one needs to depend on the browser to fetch multiple PHP files.
In the opinion of many thinkers far more knowledgeable than myself, threads are an overrated method of handling concurrency (or at least, an unnecessarily complex way to handle most situations). I would say especially this applies to someone developing in a scripting language like PHP.
If someone wants to use PHP to run tasks in parallel, multiprocessing is quite possible in PHP, and can be done without relying on the webserver (thus saving plenty of overhead). For example, you can use proc_open to open multiple instances of a commandline PHP script, with pointers for input/output. Use a stream_select loop to manage this and you can run multiple processes, while tracking the progress of each, halting them when needed, or starting new ones.
Of course, this would require that your commandline script handle STDIN and STDOUT in some sort of loop. Also, if you want distributed processing, you can use socket connections to manage these scripts on multiple servers. All quite doable, but of course well beyond the purview of your typical PHP coder.
And yes, there ARE quite legitimate uses of PHP commandline scripts, especially for cron jobs involving databases, or for simple system management scripts.
Admin
That's very, very true.
However, there are also nearly infinite other methods you can use besides a command line PHP script that are much more suited to the task.
I just know a guy who thinks that PHP is the end all, be all of languages and uses it for everything. There are some things it's meant for and some things it really isn't. In my mind, command line cron jobs can be done with other things besides PHP.
Admin
The question is not 'can' but 'should'. Of course, there are many things for which PHP is not suited. I wouldn't use it to manage my FreeBSD init system (to use a hyperbolic example). But if I had to do something in a cron that in fact related TO my PHP web applications, such as regularly prune forum threads, or some other such database/PHP sort of thing, why on earth would I want to hack together some awful Bash script to do it? Or even a Perl DBI script? I mean, if my PHP functions are already sitting in a library somewhere, why not re-use them as applicable in a cron? It works.
Admin
You don't want your web server spinning up 2000 threads on a busy day. That's why you set some maximum and share whatever resources you've chosen to make available between whoever is requesting them.
I'm pretty sure Apache pools, though. Just about every web server does. The original post about creating a new thread for every instance was probably just badly worded. Or wrong.
That, as a result, is yet another problem with this script. If you're on a shared web host (as everyone here seems to think must be the case, as if it would somehow justify this approach) then the performance of this script could actually end up being worse than the ordinary "single-threaded" approach. Why? Because the shared server might decide to schedule other requests in between the hundreds of "image tasks".
In other words, on a busy shared web host, you could end up, on average, with less than one thread tossing out those e-mail messages, whereas if you'd just done it in a single-threaded loop, the worst performance you'd see is one thread.
Should I also point out that sending out one individual message for every recipient on a list is very likely to get blacklisted as spam? BCC exists for a reason.
Admin
Admin
Actually it's probably the web server creating the threads (or processes) and maintaining a pool. Each request gets a thread, which executes the request, then the thread goes back into the pool to be reused for another request...
...unless PHP is running in CGI mode, in which case, yes, it is creating a new process (which contains a thread) for every request. This is one of the reasons why CGI mode doesn't scale to high server loads--you can't really fork() more than about 500 times per second (maximum--less if the CGI is going to do something) on a typical web hosting machine.
There are a few exotic web servers which use non-thread-based techniques at the extreme high or low ends of the performance spectrum. Servers which do asynchronous I/O in a single thread are slightly faster on a single CPU machine with all web content in RAM, but they can't do anything like standard PHP scripting.
Admin
Processes aren't threads. Processes contain threads.
Yes, there are two threads after fork(), but there is one in each of two processes, not two threads in one process. The threads do not share memory, although they do share the contents of memory, and also file descriptors, shared memory, privileges, and so on. Sometimes they share filesystem locks, sometimes not, depending on the lock type.
A lot of library code (especially I/O, UI, and database code) is not designed with fork() in mind (even if the library is designed to be multithreaded, fork() is not about threads), and generally fails after fork().
Forking within a multi-threaded application is generally a spectacularly bad idea, unless the only thing you do after fork() is terminate one of the two processes (with exit() or exec()), or you can guarantee that all threads were holding no mutexes when you forked (which is a bit difficult to do without holding a mutex to exclude the other threads from holding mutexes...).
fork() used to be a really simple idea, but then Unix got a whole lot more complicated.