Jump to content

dalecosp

Members
  • Posts

    471
  • Joined

  • Last visited

  • Days Won

    8

Posts posted by dalecosp

  1.  

     

    Can you recommend any hosting providers that are more reliable?


    Hate to say it, but most any of 'em?

    I like RootBSD.net, but it ain't Linux.  BSD is faster, but much more bare-bones, generally speaking.  I grok the command line, but not everyone does, nor does everyone wish to ....

  2. Perhaps a better question, are you even reading my posts? You DO NOT want to call file_get_contents() more than once, even if it is a local file/on the same server.

     

    <?php
    
    // start by getting your user/recipient data ... from DB?
    $data_array = however_you_get_user_data( $from_db );
    
    // Here's your basic email template.  This can be a var, HEREDOC string, whatever
    // you could use file_get_contents() to get this ... ONE TIME, preferably from
    // a local file.  It has placeholders (I've chosen to use a curly-bracket syntax
    // similar to SMARTY).
    
    $template = "
    
    Dear {user},
    
       Welcome to {name_of_site} ... blah, blah, etc.
    
    ";
    
    // this array holds the tags from the above template which are the merge fields
    $replaced_array = array( "{user}", "{name_of_site}" );
    
    //$data_array is assumed to be your multi-dimensional array of user datas...
    foreach ( $data_array as $user_data_array ) {
    
       // of course $user_data_array has to have a proper format, which would be
       // based on the needed merge fields from the template
    
       $template_to_send = str_replace($replaced_array, $user_data_array, $template );
    
       //MAILer code goes here.
    
    }
    If you choose to speak ESMTP directly to a socket, you'd need to make up an array of templates and submit them $n at a time to the mail server yourself (but it would be much faster again):

     

    <?php
    
    // start by getting your user/recipient data ... from DB?
    $data_array = however_you_get_user_data( $from_db );
    
    // Here's your basic email template
    $template = "
    
    Dear {user},
    
       Welcome to {name_of_site} ... blah, blah, etc.
    
    ";
    
    // this array holds the tags from the above template which are the merge fields
    $replaced_array = array( "{user}", "{name_of_site}" );
    
    $counter = 1;
    $template_to_send = array();
    
    //$data_array is assumed to be your multi-dimensional array of user datas...
    foreach ( $data_array as $user_data_array ) {
    
       // of course $user_data_array has to have a proper format, which would be
       // based on the needed merge fields from the template
    
       $template_to_send[$counter] = str_replace($replaced_array, $user_data_array, $template );
       $counter++;
    
       if ($counter == 100 ) { //sending 100 pieces to the socket at a time
          foreach ($template_to_send as $message) {
             //MAILer code goes here, fsockopen, fputs("EHLO hostname"), etc. etc.
        
          } //foreach
          $counter = 1; //reset counter
       } //if
    
    }//foreach $data_array ..
    
  3. Comments inline, after the "hashbang" (#!) marks ...

     

     

     

     
    function db_query($query, $logError=true, $buffered=true) {
    
        global $ost, $__db; # do $ost and $__db both exist outside this function? (Note 2 underscores)
     
        if ($__db->unbuffered_result) { #! Great ... __db is an object. We may need to see it too...
            $__db->unbuffered_result->free();
            $__db->unbuffered_result = false;
        }
     
        $tries = 3;
        do {
            $res = $__db->query($query,
                $buffered ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT);
            // Retry the query due to deadlock error (#1213)
            // TODO: Consider retry on #1205 (lock wait timeout exceeded)
            // TODO: Log warning
        } while (!$res && --$tries && $__db->errno == 1213);
     
        if(!$res && $logError && $ost) { //error reporting
            // Allow $logError() callback to determine if logging is necessary
            if (is_callable($logError) && !($logError($__db->errno))) #! Might try added brackets &&
    #! a "debug echo" statement here...
                return $res;
     
            $msg='['.$query.']'."\n\n".db_error(); #db_error is also a non-standard function.
            $ost->logDBError('DB Error #'.db_errno(), $msg);
            //echo $msg; #uncomment during debuging or dev. #! You should remove the two leading slashes
    #! and see if anything useful is printed.
        }
     
        if (is_object($res) && !$buffered)
            $__db->unbuffered_result = $res;
     
        return $res;
    }

     

    Awful lot of custom, hidden code there ... we have no clue about the $ost object or the $__db object, which are in some other classes ... probably some other files in the application.

     

    You might try doing this:

     

    function db_query($query, $logError=true, $buffered=true) {
    
        global $ost, $__db;
     
        if ($__db->unbuffered_result) {
            $__db->unbuffered_result->free();
            $__db->unbuffered_result = false;
        }
     
        $tries = 3;
        do {
            $res = $__db->query($query,
                $buffered ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT);
                } while (!$res && --$tries && $__db->errno == 1213);
    
    //DEBUG
    echo "Tries is $tries<br>\n";
     
        if(!$res && $logError && $ost) { //error reporting
        if (is_callable($logError) && !($logError($__db->errno))) {
    //DEBUG
    echo "returning without valid result<br>\n";
                return $res;
      }
            $msg='['.$query.']'."\n\n".db_error();
            $ost->logDBError('DB Error #'.db_errno(), $msg);
            echo "LogDBError message: ".$msg."<br>\n"; #uncomment during debugging or dev.
        }
     
        if (is_object($res) && !$buffered) {
            $__db->unbuffered_result = $res;
      //DEBUG
    echo "returning in bottom loop<br>\n";
        return $res;
    } else {
    die("We should not be here!");
    }
    }
  4. Can you show us the db_query function? There's no such function built into PHP, so it's likely a custom function and probably isn't doing what you want it to, either because it's broken, or because you don't understand how to use it (which could easily still be the programmer's fault if (s)he didn't document it clearly)....

  5. I am not totally sure what you are suggesting instead. Reason I am doing this is so that I can send email from two different domains.

    Perhaps I misunderstand you.  What it sounds like you are saying is this:  A loop is running, and for each item in the loop you call file_get_contents() on an external webpage, maybe something like this:

     

    $mail_body = file_get_contents("http://mysite.com/template_generator.php?firstname=$firstname&somevar=$variable");
    If that is the case, it's terribly inefficient. You need a template in memory as a variable:

     

    $mail_template = <<<EOT
    
    Dear {firstname},
    
    Are you still interested in purchasing the {name_of_product} from our web site?
    
    Thanks,
    
    MyCompany.com
    
    EOT;
    You should then call str_replace on this variable with the data for each iteration of the loop.

     

    Now it sounds like *maybe* the problem is that you can't get all your data from more than one location all up front, which is also part of what I'd be doing in this sort of situation. If you can't, that is a bit of a problem. I don't freelance much, but I do need to get my convertible out of the $hop with its $hiny new engine and exhau$t $y$tem ...

  6. And the other thing is probably this:

     

     

     

     If record checks then send email by file_get_contents passing all the email content through get variables.


    You're doing an HTTP GET to a PHP script for this?  Ouch!

    This will at least DOUBLE your throughput:  format your file a la "a template", read the file ONCE into a variable, and str_replace() the DB values into the template var.
  7. Given that this is starting to sound like I'm helping a spammer, I'm a little loath to comment; however:

    PHP is using a heck of a lot of overhead opening and closing a connection to the SMTP server. What you should do if you want to scale is to have PHP open a socket and speak directly to the SMTP server without opening and closing the connection for a given number of mails (which you should test against your SMTP server, you do NOT want to choke it to death).

    If you know how to speak SMTP, this shouldn't be too difficult.

  8. Into what table? An HTML table? A Database Table? The Dining Table?

     

    Assuming the 2nd option above (DB table), I guess, eh ... don't create a unique index?

     

    But seriously, you don't give us your DB structure, and you don't give us sample data or tell us what the data is (it appears to be an array of URLs?) ...

     

    How about this?

     

    mysql> describe xsit;
    +-------+---------+------+-----+---------+----------------+
    | Field | Type    | Null | Key | Default | Extra          |
    +-------+---------+------+-----+---------+----------------+
    | id    | int(11) | NO   | PRI | NULL    | auto_increment |
    | var   | text    | YES  |     | NULL    |                |
    +-------+---------+------+-----+---------+----------------+
    2 rows in set (0.00 sec)
    
    Seems like it would work with that?

     

     

    [edit]PS: someone will probably say "Stop using the old mysql_* functions.

     

    I agree ;)[/edit]

    • Like 1
  9. Have you tried adding PHP to your Google search string? ;)

     

    I've searched my history and bookmarks, but apparently it's been too long since I found whatever it was I learned from. And I didn't bookmark it. I do have a project running using pcntl_* functions.

     

    Prepare to write more code ;)

     

    Here's the heart of a multi-threaded "fetcher" that uses posix_getpid, pcntl_fork and pcntl_waitpid in conjunction with an external function I didn't show (systemFetchSequential(), uses fetch/wget to get urls and write them to $outpath).

     

    The function is_pid() simply returns false if the PID isn't set (probably could just use a truth check and is_int(), but I didn't and can't remember why). threaded_fetch() is limited to 10 threads by the huge if/elseif construct there; if you write more code you can have more threads. I can't recall the reason, but a switch wouldn't work according to the guy I was reading.

     

    function is_pid($n) { return ($n > 0); } //EOF
    
    function threaded_fetch( $url_array, $outpath ) {
    
    global $threads; //we get this from the calling environment
    
    if ( $threads > 10 ) die("Threaded_fetch() function cannot support more than 10 threads.");
    
    $url_chunks = array_chunk( $url_array, (ceil((count($url_array)) / $threads ))+5, true );
    
    /* PNCTL_FORK() implementation */
    
    $ppid=posix_getpid(); // Keep reference to the PID of the parent process
    $pids=array( range( 0,( $threads ) ) ); // An array to hold refrence to PIDs of child processes
    
    for ( $i = 0; $i<=$threads; $i++ ) {
    
    $pid=pcntl_fork(); // Forks a new child process and keeps refrence to its PID;
    if ( $pid == -1 ) {
    die( 'could not fork' );
    }
    if ( !$pid ) { /* This only runs in a child process */
    $pids[$i] = posix_getpid();// Get the PID of the child process
    break;
    } else {
    $pids[$i] = $pid;
    }
    } //for $i
    
    $active_pids = count(array_filter($pids,"is_pid"));
    print("Started $active_pids children to process ".count($url_chunks)." chunks of data.");
    
    /* By this time all processes, child and parent have their own copy of $pid and $pids[]*/
    
    $current_pid=posix_getpid(); // Get the PID of the curently running process
    
    if ( $current_pid == $pids[0] ) { /* Task for child 1 */
    systemFetchSequential( $url_chunks[0],"$outpath" );
    exit();
    } elseif ( $current_pid == $pids[1] ) { /* Task for child 2 */
    systemFetchSequential( $url_chunks[1],"$outpath" );
    exit();
    } elseif ( $current_pid == $pids[2] ) { /* Task for child 3 */
    systemFetchSequential($subpage_chunks[2],"$outpath");
    exit();
    } elseif ( $current_pid == $pids[3] ) { /* Task for child 4 */
    systemFetchSequential( $url_chunks[3],"$outpath" );
    exit();
    } elseif ( $current_pid == $pids[4] ) { /* Task for child 5 */
    systemFetchSequential( $url_chunks[4],"$outpath" );
    exit();
    } elseif ( $current_pid == $pids[5] ) { /* Task for child 6 */
    systemFetchSequential( $url_chunks[5],"$outpath" );
    exit();
    } elseif ( $current_pid == $pids[6] ) { /* Task for child 7 */
    systemFetchSequential( $url_chunks[6],"$outpath" );
    exit();
    } elseif ( $current_pid == $pids[7] ) { /* Task for child 8 */
    systemFetchSequential( $url_chunks[7],"$outpath" );
    exit();
    } elseif ( $current_pid == $pids[8] ) { /* Task for child 9 */
    systemFetchSequential( $url_chunks[8],"$outpath" );
    exit();
    } elseif ( $current_pid == $pids[9] ) { /* Task for child 10 */
    systemFetchSequential( $url_chunks[9],"$outpath" );
    exit();
    }
    
    foreach ( $pids as $key => $val ) { //wait/exit routine
    pcntl_waitpid( $val, $status );
    unset( $pids[$key] );
    }
    } //EOF

     

    In this case, running this function with a $url_array will start 10 children on the server, running fetch/wget against a chunk of the $url_array until they're done.

  10. You would also have to decide what the header area would look like *prior* to the JS running (even if that was only a second or two) ... it would also be what the bots/SE's see, and what any users without JavaScript enabled would see, which is, indeed, Yet Another Reason it should be done in PHP first, and then you can play JavaScript magic if it's still needed.

  11. It would be possible with JavaScript also, if you have some way to render the desired PHP on the server in response to an AJAX call.  Keep in mind that this is a pretty big project for a little bit of ... whatever.  You have to write a PHP "server" that responds to the AJAX calls and a suitable JS that will run in the browser to change the header sometime after the JavaScript that determine what country the user is in.  And *that* is the reason why you really should consider just using PHP on the server-side, but we can't determine your system requirements for you. ;)

    The basic JS execution would be something like:

    //some JS here
    if (country=="UK") {
       var thisHTML = myAjaxCall("http://myhost.com/header.php?country=UK"); // of course you must write the PHP to respond to this.
       // (and the Ajax handler)
       var myDiv = document.getElementById("header"); //whatever the document ID is
       myDiv.innerHTML = thisHTML;
    } elseif (country=="US") {
       var thisHTML = myAjaxCall("http://myhost.com/header.php?country=US");
       var myDiv = document.getElementById("header"); //whatever the document ID is
       myDiv.innerHTML = thisHTML;
    }
  12. phpMyAdmin is a reasonably good MySQL client, and it supports multiple queries in the "query" frame/tab; they must be separated with a semi-colon just as they should be in any MySQL client.  +1 for JazzMan1.

    mysql> select * from products
        -> select * from product_options;
    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that                                                                                                                                                              corresponds to your MySQL server version for the right syntax to use near 'selec                                                                                                                                                             t * from product_options' at line 2
    mysql> select * from products; select * from product_options;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | shirt |
    |  2 | shoes |
    |  3 | socks |
    +----+-------+
    3 rows in set (0.16 sec)
     
    +----+------------+-------+--------+
    | id | product_id | name  | value  |
    +----+------------+-------+--------+
    |  1 |          1 | color | red    |
    |  2 |          1 | color | blue   |
    |  3 |          1 | color | green  |
    |  4 |          3 | color | black  |
    |  5 |          3 | color | white  |
    |  6 |          2 | color | black  |
    |  7 |          2 | color | purple |
    +----+------------+-------+--------+
    7 rows in set (0.08 sec)
    
  13. Welcome to PHPFreaks. :)

    MySQL Workbench is a client program, if I remember correctly.  [?]

    You probably need "community server":  http://dev.mysql.com/downloads/mysql/

    The Server Software is the actual "database", holds the data, etc.  You'd probably install it as a service, then use MySQL Workbench to connect to it, create queries, and so on, without having to program them (with 'R', I assume?)   #include disclaimer.h, YMMV, Idiots on the 'Web are not responsible if you blow up your system &c...

    Your "R" program would also need to connect to the MySQL service to do its stats munging and so forth....

    Incidentally, since this forum is mostly about PHP, I doubt you'll find many people who know much about 'R'.  I've heard of it ... that's about it.

    Best of luck :)

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.