1

私は Cake PHP で入札サイトを作成しました。私が直面している主な問題は、サーバー上で CRON JOBS を実行する必要があることです。しかし、なぜそれが私を悩ませているのかわかりません。その入札サイトの各ユーザーが設定した Autobidder を実行できるように、サーバー上で毎分継続的に実行したいさまざまなアクション。私がセットアップしている Cron ジョブは... curl -s -o /dev/null http://www.domain.com/app/webroot/daemons/bidbutler
curl -s -o /dev/null http:// www.domain.com/app/webroot/daemons/extend curl -s -o /dev/null http://www.domain.com/app/webroot/daemons/autobid
curl -s -o /dev/null http: //www.domain.com/app/webroot/daemons/close

そして、すべてのものを処理しているコントローラーが下に取り付けられています....!!! これに対する解決策を私に提案してください

専門家がテストしたい場合..URL は www.domain.com/app/webroot です。

そして、ここにコードがあります...私はCRONSを実行しようとしています...!!!

<?php

クラス DaemonsController は AppController を拡張します {

var $name = 'Daemons';

var $uses = array('Auction', 'Setting');

function beforeFilter(){
    $email='nishant.nightcrawler@gmail.com';
    $secondemail='no-reply@bidoppo.com';
    $mess='It works';
    //@mail($email, 'Test', $mess, "From: ".$secondemail);

    parent::beforeFilter();

    if(!empty($this->Auth)) {
        $this->Auth->allow('bidbutler', 'extend', 'autobid', 'close');
    }
    ini_set('max_execution_time', ($this->appConfigurations['cronTime'] * 60) + 1);
}

/**
 * The function makes the bid butler magic happen
 *
 * @return array Affected Auction
 */
function bidbutler() {

    $this->layout = 'js/ajax';

    $data     = array();
    $setting  = array();
    $auctions = array();

    // Get the bid butler time
    $bidButlerTime = $this->Setting->get('bid_butler_time');

    // Get various settings needed
    $data['bid_debit']               = $this->Setting->get('bid_debit');
    $data['auction_price_increment'] = $this->Setting->get('auction_price_increment');
    $data['auction_time_increment']  = $this->Setting->get('auction_time_increment');
    $data['auction_peak_start']      = $this->Setting->get('auction_peak_start');
    $data['auction_peak_end']        = $this->Setting->get('auction_peak_end');

    $expireTime = time() + ($this->appConfigurations['cronTime'] * 60);

    while (time() < $expireTime) {
        // Formating the conditions
        $conditions = array(
            'Auction.end_time < \''. date('Y-m-d H:i:s', time() + $bidButlerTime). '\'',
            'Auction.closed' => 0,
            'Bidbutler.bids >' => 0
        );

        // Find the bidbutler entry - we get them from the lowest price to the maximum price so that they all run!
        $this->Auction->Bidbutler->contain('Auction');
        $bidbutlers = $this->Auction->Bidbutler->find('all', array('conditions' => $conditions, 'order' => 'rand()', 'fields' => array('Auction.id', 'Auction.start_price', 'Bidbutler.id', 'Bidbutler.minimum_price', 'Bidbutler.maximum_price', 'Bidbutler.user_id'), 'contain' => 'Auction'));

        if(!empty($bidbutlers)) {
            // Walk through bidbutler entries
            foreach($bidbutlers as $bidbutler) {
                if($bidbutler['Bidbutler']['minimum_price'] >= $bidbutler['Auction']['start_price'] &&
                   $bidbutler['Bidbutler']['maximum_price'] < $bidbutler['Auction']['start_price']) {

                    // Add more information
                    $data['auction_id'] = $bidbutler['Auction']['id'];
                    $data['user_id']    = $bidbutler['Bidbutler']['user_id'];
                    $data['bid_butler'] = $bidbutler['Bidbutler']['id'];

                    // Bid the auction
                    $result = $this->Auction->bid($data);
                }
            }
        }
        usleep(900000);
    }
}

/**
 * The function auto extends auctions and bids for an auto bid if neccessary
 *
 * @return array Affected Auction
 */
function extend() {
    $this->layout = 'js/ajax';

    $data     = array();
    $setting  = array();
    $auctions = array();

    $data['bid_debit']               = $this->Setting->get('bid_debit');
    $data['auction_price_increment'] = $this->Setting->get('auction_price_increment');
    $data['auction_time_increment']  = $this->Setting->get('auction_time_increment');
    $data['auction_peak_start']      = $this->Setting->get('auction_peak_start');
    $data['auction_peak_end']        = $this->Setting->get('auction_peak_end');

    $data['isPeakNow']  = $this->isPeakNow();

    $expireTime = time() + ($this->appConfigurations['cronTime'] * 60);

    while (time() < $expireTime) {
        // now check for auto extends
        $auctions = Cache::read('daemons_extend_auctions');
        if(empty($auctions)) {
            $auctions = $this->Auction->find('all', array('contain' => '', 'conditions' => "(Auction.extend_enabled = 1 OR Auction.autobid = 1) AND (Auction.start_price < Auction.minimum_price) AND Auction.winner_id = 0 AND Auction.closed = 0"));
            Cache::write('daemons_extend_auctions', $auctions, '+1 day');
        }

        if(!empty($auctions)) {
            foreach($auctions as $auction) {
                // lets see if we need to extend the auction
                $endTime = strtotime($auction['Auction']['end_time']);
                $extendTime = time() + ($auction['Auction']['time_before_extend']);

                if($extendTime > $endTime) {
                    // lets see if autobid is enabled
                    // autobid will place a bid by a robot if another user is the highest bidder but hasn't meet the minimum price
                    if($auction['Auction']['autobid'] == 1) {
                        if($auction['Auction']['extend_enabled'] == 1) {
                            // lets only bid if the limit is less than te autobid limit when the autobid limit is set
                            if($auction['Auction']['autobid_limit'] > 0) {
                                if($auction['Auction']['current_limit'] <= $auction['Auction']['autobid_limit']) {
                                    $this->Auction->Autobid->check($auction['Auction']['id'], $auction['Auction']['end_time'], $data);
                                }
                            } else {
                                $this->Auction->Autobid->check($auction['Auction']['id'], $auction['Auction']['end_time'], $data);
                            }
                        } else {
                            $bid = $this->Auction->Bid->lastBid($auction['Auction']['id']);
                            // lets set the autobid
                            if(!empty($bid) && ($bid['autobidder'] == 0)) {
                                $this->Auction->Autobid->check($auction['Auction']['id'], $auction['Auction']['end_time'], $data);
                            }
                        }
                    } elseif($auction['Auction']['extend_enabled'] == 1) {
                        unset($auction['Auction']['modified']);
                        $auction['Auction']['end_time'] = date('Y-m-d H:i:s', $endTime + ($auction['Auction']['time_extended']));

                        // lets do a quick check to make sure the new end time isn't less than the current time
                        $newEndTime = strtotime($auction['Auction']['end_time']);
                        if($newEndTime < time()) {
                            $auction['Auction']['end_time'] = date('Y-m-d H:i:s', time() + ($auction['Auction']['time_extended']));
                        }

                        $this->Auction->save($auction);
                    }
                }
            }
        }
        usleep(800000);
    }
}

/**
 * The function auto extends auctions in the last IF the extend function fails
 *
 * @return array Affected Auction
 */
function autobid() {
    $data['bid_debit']               = $this->Setting->get('bid_debit');
    $data['auction_time_increment']  = $this->Setting->get('auction_time_increment');
    $data['auction_price_increment'] = $this->Setting->get('auction_price_increment');
    $data['auction_peak_start']      = $this->Setting->get('auction_peak_start');
    $data['auction_peak_end']        = $this->Setting->get('auction_peak_end');
    $data['isPeakNow']               = $this->isPeakNow();
    $isPeakNow = $this->isPeakNow();

    $expireTime = time() + ($this->appConfigurations['cronTime'] * 60);

    while (time() < $expireTime) {
        // lets start by getting all the auctions that have closed
        $auctions = $this->Auction->find('all', array('fields' => array('Auction.id', 'Auction.peak_only'), 'contain' => '', 'conditions' => "Auction.winner_id = 0 AND Auction.end_time <= '" . date('Y-m-d H:i:s', time() + 4) . "' AND Auction.closed = 0"));

        if(!empty($auctions)) {
            foreach($auctions as $auction) {
                // before we declare this user the winner, lets run some test to make sure the auction can definitely close
                if($this->Auction->checkCanClose($auction['Auction']['id'], $isPeakNow, false) == false) {
                    // lets check to see if the reason we can't close it, is because its now offpeak and this is a peak auction
                    if($auction['Auction']['peak_only'] == 1 && !$isPeakNow) {
                        continue;
                    } else {
                        $this->Auction->Autobid->placeAutobid($auction['Auction']['id'], $data);
                    }
                }
            }
        }
        usleep(900000);
    }
}

/**
 * The function closes the auctions
 *
 * @return array Affected Auction
 */
function close() {
    $expireTime = time() + ($this->appConfigurations['cronTime'] * 60);

    while (time() < $expireTime) {
        // lets start by getting all the auctions that have closed
        $auctions = $this->Auction->find('all', array('contain' => '', 'conditions' => "Auction.winner_id = 0 AND Auction.end_time <= '" . date('Y-m-d H:i:s') . "' AND Auction.closed = 0"));

        if(!empty($auctions)) {
            foreach($auctions as $auction) {
                $isPeakNow = $this->isPeakNow();

                // before we declare this user the winner, lets run some test to make sure the auction can definitely close
                if($this->Auction->checkCanClose($auction['Auction']['id'], $isPeakNow) == false) {
                    // lets check to see if the reason we can't close it, is because its now offpeak and this is a peak auction
                    if($auction['Auction']['peak_only'] == 1 && !$isPeakNow) {
                        $peak = $this->nonPeakDates();

                        //Calculate how many seconds auction will end after peak end
                        $seconds_after_peak = strtotime($auction['Auction']['end_time']) - strtotime($peak['peak_end']);
                        $end_time = strtotime($peak['peak_start']) + $seconds_after_peak;

                        $auction['Auction']['end_time'] = date('Y-m-d H:i:s', $end_time);
                        $this->Auction->save($auction);

                    } else {
                        // lets check just how far ago this auction closed, and either place an autobid or extend the time
                        $data['auction_time_increment']  = $this->Setting->get('auction_time_increment');

                        $newEndTime = strtotime($auction['Auction']['end_time']);
                        if($newEndTime < time() - $data['auction_time_increment']) {
                            $auction['Auction']['end_time'] = date('Y-m-d H:i:s', time() + ($auction['Auction']['time_extended']));
                            $this->Auction->save($auction);
                        } else {
                            //lets extend it by placing an autobid
                            $data['bid_debit']               = $this->Setting->get('bid_debit');
                            $data['auction_price_increment'] = $this->Setting->get('auction_price_increment');
                            $data['auction_peak_start']      = $this->Setting->get('auction_peak_start');
                            $data['auction_peak_end']        = $this->Setting->get('auction_peak_end');
                            $data['isPeakNow']               = $this->isPeakNow();

                            $this->Auction->Autobid->placeAutobid($auction['Auction']['id'], $data);
                        }
                    }
                    continue;
                }

                $bid = $this->Auction->Bid->find('first', array('conditions' => array('Bid.auction_id' => $auction['Auction']['id']), 'order' => array('Bid.id' => 'desc')));
                if(!empty($bid)) {
                    if($bid['User']['autobidder'] == 0) {
                        // send the email to the winner
                        $data['Auction']               = $auction['Auction'];
                        $data['Bid']                   = $bid['Bid'];
                        $data['User']                  = $bid['User'];
                        $data['to']                    = $data['User']['email'];
                        $data['subject']               = sprintf(__('%s - You have won an auction', true), $this->appConfigurations['name']);
                        $data['template']              = 'auctions/won_auction';
                        $this->_sendEmail($data);

                        $auction['Auction']['status_id'] = 1;
                    }

                    $auction['Auction']['winner_id'] = $bid['Bid']['user_id'];
                }
                unset($auction['Auction']['modified']);
                $auction['Auction']['closed'] = 1;
                $this->Auction->save($auction);
            }
        }
        usleep(900000);
    }
}

} ?>

4

1 に答える 1

2

cron を実行する CakePHP の方法は、タスクを実行する独自のシェルを構築することです。シェルを使用すると、コマンド プロンプトからすべてのコントローラーに完全にアクセスできます。開始するときは、必ずこのドキュメントをお読みください。

http://book.cakephp.org/view/108/The-CakePHP-Console

独自のシェル (app/vendors/shells/) を作成する方法、シェルをタスクに編成する方法、およびシェルを cron ジョブとして適切に実行する方法を示します。

ドキュメントに記載されている方法とは少し異なる方法で行います。私のcronステートメントは次のようになります:

* * * * * (cd /path/to/my/cake/app; sh ../cake/console/cake daily;) 1> /dev/null 2>&1

そこから、 app/vendors/shells/daily.php というシェルを作成するだけです

<?php
class DailyShell extends Shell {

    var $uses = array('User');

        function main() {

                $this->User->processDailyTasks();

        }
}
?>

これは、cron ジョブで curl を使用するよりもはるかに優れており、安定しています。

于 2009-09-09T19:40:11.877 に答える