• (cs)

    thread.php?from=1&to=1000; DROP TABLE mailing_list_table

    ...

    Edit: http://www.devnetwork.net/forums/viewtopic.php?t=11776

  • mol (unregistered) in reply to Evo
    Evo:
    thread.php?from=1&to=1000; DROP TABLE mailing_list_table

    no problem, mysql_query executes only first sql statement...

  • NameNotFoundException (unregistered)

    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.

  • Russ (unregistered) in reply to NameNotFoundException

    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).

  • kingofnothing44 (unregistered)

    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.

  • (cs)

    <sarcasm class="pity">GENIUS!!!</sarcasm>

  • zbigg (unregistered)

    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.

  • Ryan (unregistered) in reply to Russ

    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)

  • (cs) in reply to shaunburdick
    shaunburdick:
    <sarcasm class="pity">GENIUS!!!</sarcasm>
    You must be new here. The correct term is 'Brillant!'
  • Anon (unregistered)

    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?

  • aaron (unregistered)

    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.

  • Hairy (unregistered)

    Brillant!

  • dkf (unregistered)

    Oh lovely! Side effects from a GET, just what we always needed...

  • Anonymous (unregistered)

    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.

  • (cs) in reply to Russ
    Russ:
    You know, since PHP probably doesn't have a way to do multithreading

    Actually it does: http://ca.php.net/manual/en/function.pcntl-fork.php

  • SlyEcho (unregistered) in reply to kingofnothing44
    kingofnothing44:
    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
    It's not the loop that creates threads by itself. The loop writes img tags the the HTML. The browser will request each image from the server. These requests are executed in different threads on the web server so it really kind of does work. The amount of threads that will be parallelly executed depends on how many simultaneous requests a given web browser will make.
  • Martin (unregistered)

    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.

  • TwelveBaud (unregistered)

    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 (!)

  • nixen (unregistered) in reply to SlyEcho
    SlyEcho:
    kingofnothing44:
    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
    It's not the loop that creates threads by itself. The loop writes img tags the the HTML. The browser will request each image from the server. These requests are executed in different threads on the web server so it really kind of does work. The amount of threads that will be parallelly executed depends on how many simultaneous requests a given web browser will make.
    So.. you're saying that the php engine creates a new thread for every incoming request?!? Not being sarcastic, I know nothing at all about php, but this just sounds... well.. wrong..
  • Grant (unregistered)

    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 />
  • (cs) in reply to Lingerance

    Technically that makes a new process, not a new thread.

    Addendum (2007-08-13 10:14): Oops, this was in reply to:

    Lingerance:
    Russ:
    You know, since PHP probably doesn't have a way to do multithreading

    Actually it does: http://ca.php.net/manual/en/function.pcntl-fork.php

  • MntlChaos (unregistered) in reply to nixen
    nixen:
    SlyEcho:
    kingofnothing44:
    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
    It's not the loop that creates threads by itself. The loop writes img tags the the HTML. The browser will request each image from the server. These requests are executed in different threads on the web server so it really kind of does work. The amount of threads that will be parallelly executed depends on how many simultaneous requests a given web browser will make.
    So.. you're saying that the php engine creates a new thread for every incoming request?!? Not being sarcastic, I know nothing at all about php, but this just sounds... well.. wrong..

    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.

  • w00t (unregistered) in reply to nixen
    nixen:
    So.. you're saying that the php engine creates a new thread for every incoming request?!? Not being sarcastic, I know nothing at all about php, but this just sounds... well.. wrong..

    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!

  • Foo (unregistered) in reply to Russ
    Russ:
    ...I don't have to worry about silly language limits like this since I code in ColdFusion and can ...

    hahahahahahaha... seriously now.

  • Mr. Garrison (unregistered)
    Despite what our teachers may have said, there is such a thing as a stupid question.
    There are no stupid questions, only stupid people!
  • SomeCoder (unregistered)

    ... 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.

  • kastein (unregistered) in reply to Russ
    Russ:
    ...since I code in ColdFusion and can always write a piece in pure Java if necessary, as CF runs on top of Java...
    WHY in God's name would you do this?!
    Russ:
    ...but this seems a pretty brilliant way to do multithreading...
    Oh, nevermind my previous question. You can go about your WTF business.
  • xL (unregistered)

    Uhm, ugly hack as this is, it isn't even multithreading proper. The different 'threads' do not share the same variable/memory space.

  • Jason Lotito (unregistered)

    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.

  • Matt (unregistered) in reply to Foo
    Foo:
    Russ:
    ...I don't have to worry about silly language limits like this since I code in ColdFusion and can ...

    hahahahahahaha... seriously now.

    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?"

  • (cs) in reply to SomeCoder

    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.

  • (cs)

    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>
  • Who Me? (unregistered)

    "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?

  • NickF (unregistered) in reply to Lingerance
    Lingerance:
    Russ:
    You know, since PHP probably doesn't have a way to do multithreading

    Actually it does: http://ca.php.net/manual/en/function.pcntl-fork.php

    from that page, in the example given:

    pcntl_wait($status); //Protect against Zombie children
    now THAT'S what I call a useful function.
  • aaron (unregistered) in reply to kastein
    kastein:
    WHY in God's name would you do this?!

    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

  • qdfqsdfqsdfqsdfqsdf (unregistered) in reply to aaron
    aaron:
    kastein:
    WHY in God's name would you do this?!

    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

    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.

  • Annonymous (unregistered) in reply to LiquidFire
    LiquidFire:
    Technically that makes a new process, not a new thread.

    Addendum (2007-08-13 10:14): Oops, this was in reply to:

    Lingerance:
    Russ:
    You know, since PHP probably doesn't have a way to do multithreading

    Actually it does: http://ca.php.net/manual/en/function.pcntl-fork.php

    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.

  • Nodren (unregistered)

    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

  • Michael (unregistered) in reply to nixen
    nixen:
    So.. you're saying that the php engine creates a new thread for every incoming request?!? Not being sarcastic, I know nothing at all about php, but this just sounds... well.. wrong..
    Actually the PHP engine is executed by the webserver. Depending on the web server, it will create either a new thread, or a new process, for every incoming request, regardless of if it is going to then run PHP or not. You seem to think this is a bad idea, but how else would you expect a web server to service multiple requests at a time?
  • Alvin Douchewater (unregistered) in reply to Martin
    Martin:
    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.

    Never bite the task at hand that feeds you.

  • Alvin Douchewater (unregistered) in reply to Martin
    Martin:
    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.

    Never bite the task at hand that feeds you.

  • Dmitriy Kropivnitskiy (unregistered)

    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).

  • Anonymous (unregistered)

    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).

  • rycamor (unregistered)

    WTF-able from both aspects:

    1. Thinking that "running scripts in parallel" requires "multithreading".

    2. 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.

  • SomeCoder (unregistered) in reply to rycamor
    rycamor:

    And yes, there ARE quite legitimate uses of PHP commandline scripts, especially for cron jobs involving databases, or for simple system management scripts.

    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.

  • rycamor (unregistered) in reply to SomeCoder
    SomeCoder:
    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.

    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.

  • (cs) in reply to Michael
    Michael:
    nixen:
    So.. you're saying that the php engine creates a new thread for every incoming request?!? Not being sarcastic, I know nothing at all about php, but this just sounds... well.. wrong..
    Actually the PHP engine is executed by the webserver. Depending on the web server, it will create either a new thread, or a new process, for every incoming request, regardless of if it is going to then run PHP or not. You seem to think this is a bad idea, but how else would you expect a web server to service multiple requests at a time?
    Ever heard of pooling?

    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.

  • gygax (unregistered) in reply to Mr. Garrison
    Mr. Garrison:
    Despite what our teachers may have said, there is such a thing as a stupid question.
    There are no stupid questions, only stupid people!
    Only stupid people believe that quote. There really are stupid questions.
  • Zygo (unregistered) in reply to nixen
    nixen:
    So.. you're saying that the php engine creates a new thread for every incoming request?!? Not being sarcastic, I know nothing at all about php, but this just sounds... well.. wrong..

    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.

  • Zygo (unregistered) in reply to Lingerance
    Lingerance:
    Russ:
    You know, since PHP probably doesn't have a way to do multithreading

    Actually it does: http://ca.php.net/manual/en/function.pcntl-fork.php

    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.

Leave a comment on “Multi-threaded PHP ”

Log In or post as a guest

Replying to comment #149344:

« Return to Article