Automatisch een opdracht repeteren zonder CronJob

Status
Niet open voor verdere reacties.

pilootnour5

Terugkerende gebruiker
Lid geworden
22 nov 2008
Berichten
1.895
Beste forumleden,

Ik beheer een website waar gebruikers hun brandstofkosten en andere autokosten kunnen monitoren. Hierna kan de gebruiker in een heel makkelijk overzicht zien hoe duur de auto nou precies is, wat de kosten per kilometer zijn, etc.

Hoe werkt het nu?
Als je kosten hebt gemaakt, bijvoorbeeld je motorolie aangevuld, dan kun je deze invoeren als kosten op de website. Vervolgens wordt de opdracht opgeslagen in een MySQL tabel. Details zoals prijs en kosten-type staan allemaal in de rij.

Nu is het zo dat je bij vaste kosten vaak repeterende kosten hebt, zoals de motorrijtuigenbelasting en de verzekering. Deze kosten komen maandelijks terug. Het is niet praktisch en ook gewoon onhandig om iedere maand of ieder kwartaal je motorrijtuigenbelasting en je verzekering in te moeten voeren. Het leek me daarom handiger dat je als gebruiker de eerste keer de gegevens van bijv de verzekering invoert, en dat je vervolgens de opdracht laat herhalen (iedere maand of iets dergelijks).

Mijn website ondersteunt geen CronJobs, en ik wil liever ook geen gebruik maken van cronjobs van andere websites, zodat ik niet afhankelijk wordt van die websites.
Een van de ideeën die ik had, was om de datum van invoeren van de kosten te vergelijken met de huidige datum, en daarmee te berekenen hoeveel er tot nu toe betaald is.
Voorbeeld:
1-1-2016 ingevoerd dat er maandelijks 25 euro betaald wordt aan autoverzekering, wordt maandelijks herhaald.
Op 1-1-2017 is de tijd tussen invoeren en de huidige tijd 12 maanden, en dus is er 25 x 12 = 300 aan verzekering betaald.

Nu komt het probleem met deze methode: Wat gebeurt er als je bijvoorbeeld van verzekering verandert, en je vanaf datum x een ander bedrag gaat betalen? Het komt erop neer dat dit misschien niet de beste methode is.

Mijn vraag is of iemand een andere slimme manier kent, of misschien een verbetering kent van mijn huidige idee waarmee ik dan toch dat laatste probleem kan tackelen.
 
Bekijk database TRIGGER (als iets verandert doe ...)(let op ketting reacties waardoor uw database blijft aanpassingen doen en er een dead loop ontstaat)

wat je best ook doet is met transacties werken zodat query reeksen elkaar niet kruisen.

cron kan je zelf ook maken door while sleep en exit te gebruiken.
 
Laatst bewerkt:
Als je geen cronjob gebruikt, dan ben je dus afhankelijk van je bezoekers. Als je exact op een bepaald tijdstip een berekening wilt maken, waar ook andere gebruikers bij betrokkenzijn, dan is een nagemaakte cronjob niet aan te bevelen. Ook zware scripts zijn niet aan te bevelen, omdat dit dan weer extra laadtijd kost voor de gebruiker.

Cronjobs op een Linux-server draaien precies op het juiste tijdstip, en zijn ook speciaal bedoeld om het laden van pagina's bij gebruikers te ontlasten.

Waarom informeer je niet naar mogelijkheden tot cronjobs/geplande taken bij je hosting?
 
Ik maak gebruik van een Shared Hosting. De beperking hierbij is dat cronjobs niet mogelijk zijn. Vandaar dat ik het op een andere manier probeer op te lossen. Bedankt voor de reacties in ieder geval
 
Op Shared Hosting zou het prima kunnen, in het algemeen. Is het geen mogelijkheid om een VPS aan te schaffen of wat goedkoper: een reseller-pakket?

Persoonlijk zou ik administratie-gebaseerde websites niet op een Shared Hosting omgeving zetten. Ik weet niet precies wat je allemaal opslaat. En er hoeft maar één iemand een lekke website te hebben en wie weet ligt alles van jouw ook op straat.

Welke hosting zit je nu dan?
 
Laatst bewerkt:
cronjobs zijn onmogelijk te weigeren als ze niet expliciet zeggen dat het niet mag.
dus je maakt een script (zal blijven lopen en denk ook aan maximum exec time)
je roept het script 1x aan en blijft draaien tot de appache wordt herstart of reload .
maar als je het maakt plaats het zeker hier even zodat ik kan controleren of het juist zit en je de server niet zal doden of killen.
(alle andere grotere systemen gebruiken een variant van iets met while sleep en die of exit)
 
Laatst bewerkt:
De host is One.com. Zij ondersteunen geen Cronjobs. Dat ik zelf een script elke dag laat uitvoeren moet ik zelf weten inderdaad, maar daar heb ik het materiaal niet voor. (geen computer die dag en nacht aanstaat)

edit:
Ik maak liever geen gebruik van externe websites. Naast dat het weer extra kosten met zich meebrengt wil ik er niet afhankelijk van zijn. Vandaar dat de vraag was of er een andere manier van denken voor was.
 
Laatst bewerkt:
Dan zou ik maar eens overstappen naar een andere hosting, of kijken of je een VPS kan nemen, om de genoemde reden.
Dan kan je ook meteen vaak SSL op je site zetten met een groen slotje. Hoewel dat ook vaak kan op Shared Hosting.
 
SSL kan inderdaad ook op deze host. Ik ben heel tevreden over deze host, dus ik stap liever niet over. Ik zal maar even verder moeten zoeken naar een andere soort oplossing.
 
Maar waarom draai je een administratie-systeem op een Shared Hosting? Dat verbaast mij een beetje. ;)
Zoiets wil je graag geïsoleerd hebben. Stel je voor dat iemand op de server een dDOS-attack krijgt, en je site er een paar uur uitligt. Dan kunnen je klanten hun administratie niet bijhouden. Je kan ook Ddos vervangen voor een ander soort storing waarbij iemand bijv. alle capaciteit op de server opslokt die dan onderuit gaat.

Ik weet ook niet hoe groot je berekeningen zijn die je maakt, maar dit zorgt voor traagheid bij je gebruikers, als je ze via hen laat uitvoeren. Ook niet echt een goede optie.

Ik heb het idee dat je te makkelijk over de opzet denkt. ;)
 
De host is One.com. Zij ondersteunen geen Cronjobs. Dat ik zelf een script elke dag laat uitvoeren moet ik zelf weten inderdaad, maar daar heb ik het materiaal niet voor. (geen computer die dag en nacht aanstaat)

edit:
Ik maak liever geen gebruik van externe websites. Naast dat het weer extra kosten met zich meebrengt wil ik er niet afhankelijk van zijn. Vandaar dat de vraag was of er een andere manier van denken voor was.

Maar dat is nu wat ik bedoel dat je het zelf kan doen en het werkt tot appache herstart ik wil kijken om een run te doen naar hosting (dan prive zonder mensen de url kunnen zien)

en cron script zouden er zo kunnen uitzien
PHP:
namespace start;
class Crons_model extends \Model{
    private $ingoredlist=array();
    public $states = ['PROGRESS'=>'progress','ERROR' => 'error','ACTIVE' => 'active','INACTIVE' => 'inactive'];
    public $paramtype = ['POST'=>'post','GET' => 'get'];
    public $repetitions = ['DAY'=>'day','MONTH' => 'month','HOUR' => 'hour','YEAR' => 'year'];
    protected $isinstalled = false;
    protected $startkey = 'ditiseensleutelzodatanderenhetnietkunnenaanroepen';
    public function __install(){
           if(!$this->existTableCrons()){
                $dbSql = 'CREATE TABLE IF NOT EXISTS `'.\DBConn::getTableNameFor('crons').'`(
                        `id`  INT(10) NOT NULL AUTO_INCREMENT,
                        `url`  varchar(230) COLLATE '.\DBConn::getCOLLATE().' NOT NULL,
                        `info`  varchar(2000) COLLATE '.\DBConn::getCOLLATE().' NOT NULL,
                        `STATUS` ENUM(\''.implode('\',\'',array_keys($this->states)).'\')NOT NULL ,
                        `REPETITION` ENUM(\''.implode('\',\'',array_keys($this->repetitions)).'\')NOT NULL ,
                        `ENABLED` ENUM(\'TRUE\',\'FALSE\')NOT NULL DEFAULT \'TRUE\',
                        `LOGIT` ENUM(\'TRUE\',\'FALSE\')NOT NULL DEFAULT \'FALSE\',
                        `priority` INT(4)ZEROFILL DEFAULT 0,
                        `lastrun` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,
                         PRIMARY KEY (`id`)
                    )ENGINE = InnoDB DEFAULT CHARSET='.\DBConn::getCHARSET().' COLLATE='.\DBConn::getCOLLATE().';';
                $result1 = $this->DB->query($dbSql);
                $return1 = $result1->rowCount()==1;
           }else{
                $return1 = true;
           }
           if(!$this->existTableCrons_parameters()){
                $dbSql = 'CREATE TABLE IF NOT EXISTS `'.\DBConn::getTableNameFor('crons_parameters').'`(
                        `cron_id`  INT(10),
                        `key`  varchar(150) COLLATE '.\DBConn::getCOLLATE().' NOT NULL,
                        `value` varchar(150) COLLATE '.\DBConn::getCOLLATE().' NOT NULL,
                        `TYPE` ENUM(\''.implode('\',\'',array_keys($this->paramtype)).'\')NOT NULL ,
                         PRIMARY KEY (`cron_id`,`key`)
                    )ENGINE = InnoDB DEFAULT CHARSET='.\DBConn::getCHARSET().' COLLATE='.\DBConn::getCOLLATE().';';
                $result2 = $this->DB->query($dbSql);
                $return2 = $result2->rowCount()==1;
           }else{
                $return2 = true;
           }
           if(!$this->existTableCrons_settings()){
                $dbSql = 'CREATE TABLE IF NOT EXISTS `'.\DBConn::getTableNameFor('crons_settings').'`(
                        `cron_id`  INT(10),
                        `VISIBLE` ENUM(\'TRUE\',\'FALSE\')NOT NULL DEFAULT \'TRUE\',
                        `FOLLOW` ENUM(\'TRUE\',\'FALSE\')NOT NULL DEFAULT \'FALSE\',
                        `inf`  varchar(230) COLLATE '.\DBConn::getCOLLATE().' NOT NULL,
                        `risklevel` INT(4)ZEROFILL DEFAULT 0,
                         PRIMARY KEY (`cron_id`)
                    )ENGINE = InnoDB DEFAULT CHARSET='.\DBConn::getCHARSET().' COLLATE='.\DBConn::getCOLLATE().';';
                $result3 = $this->DB->query($dbSql);
                $return3 = $result3->rowCount()==1;
            }else{
                $return3 = true;
            }
            if(!$this->existTableCrons_log()){
                $dbSql = 'CREATE TABLE IF NOT EXISTS `'.\DBConn::getTableNameFor('crons_logs').'`(
                        `cron_id`  INT(10),
                        `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
                        `CHECKED` ENUM(\'TRUE\',\'FALSE\')NOT NULL DEFAULT \'FALSE\',
                        `DONE` ENUM(\'TRUE\',\'FALSE\')NOT NULL DEFAULT \'FALSE\',
                         PRIMARY KEY (`cron_id`)
                    )ENGINE = InnoDB DEFAULT CHARSET='.\DBConn::getCHARSET().' COLLATE='.\DBConn::getCOLLATE().';';
                $result4 = $this->DB->query($dbSql);
                $return4 = $result4->rowCount()==1;
            }else{
                
                $return4 = true;
            }
        return $return2 && $return1 && $return3 && $return4 ;
    }
    public function isInstalled(){
        return $this->isinstalled ||
        $this->existTableCrons()&&
        $this->existTableCrons_parameters()&& 
        $this->isinstalled=true;
    }
    public function iskey($key){
        return $key == $this->startkey;
    }
    private function existTableCrons(){
        return $this->existTableLabel('crons');
    }
    private function existTableCrons_parameters(){
        return $this->existTableLabel('crons_parameters');
    }
    private function existTableCrons_settings(){
        return $this->existTableLabel('crons_settings');
    }
    private function existTableCrons_log(){
        return $this->existTableLabel('crons_logs');
    }

    public function getRuleDefault(){
        return 'KING';
    }
    public function getModelInfo(){
        return 'Crons.model.info';
    }
    public function getVersionNr(){
        return (float)3.0;
    }
    protected function GET_Crons($enabled,$repetition){
        $c = \DBConn::getTableNameFor('crons');
        $sql='SELECT `'.$c.'`.* FROM `'.$c.'`';
        $where = '';
        $link =' WHERE';
        
        if(!empty($enabled)&&$enabled==true){
            $where.= $link.' `'.$c.'`.`ENABLED`=\'TRUE\'';                  $link =' && '; 
        }
        $sql.= $where;
        $this->paginator->setSort(' group by `'.$c.'`.`id` ORDER BY `'.$c.'`.`lastrun` DESC ');
        $this->paginator->setRange(13);
        print $sql;
        return $sql;
    }   
    public function getCrons($repetition){
       $c = \DBConn::getTableNameFor('crons');
       //`lastrun`
       $sql='SELECT id as \'key\' , url as \'value\' FROM `'.$c.'` WHERE  `ENABLED`=\'TRUE\' and `STATUS`=\'ACTIVE\' '  .((isset($repetition))?' AND   `REPETITION`=\''.$repetition.'\'':'').' ORDER BY `priority`' ;
       //print $sql;
       return parent::GET_Array($sql);
    }
    public function getParams($cron_id){
       $c = \DBConn::getTableNameFor('crons_parameters');
       $sql='SELECT id as \'key\' , url as \'value\' FROM `'.$c.'` WHERE  `cron_id`=\''.$cron_id.'\'';
       return parent::GET_Array($sql);
    }
    public function addParams($cron_id,$params){

        }

    private function hasParam($cron_id,$param){
        $p = \DBConn::getTableNameFor('crons_parameters');
        $sql = 'SELECT `'.$p.'`.`rule_id` FROM `'.$p.'` WHERE `id`=:id AND `user_rullset`.`TYPE`=:type ';
        $param = [':cronid'=>$cron_id , ':param'=>$param];
        return $this->isQuery($sql,$param);
    }
    public function log(){
        
    }
    public function save($url,$info,$STATUS, $REPETITION,$ENABLED,$LOGIT,$priority){
        $c = \DBConn::getTableNameFor('crons');
        $key ='INSERT INTO `'.$c.'`(`id`,`url`,`info`, `STATUS`, `REPETITION`,`ENABLED`,`LOGIT`,`priority`) '.
              'VALUES(NULL ,:url ,:info ,:STATUS ,:REPETITION ,:ENABLED,:LOGIT,:priority) RETURNING `id`';
        $value = [':url'=>$url,
        ':info'=>$info,
        ':STATUS'=>$STATUS,
        ':REPETITION'=>$REPETITION,
        ':ENABLED'=>$ENABLED,
        ':LOGIT'=>$LOGIT,
        ':priority'=>$priority,
        ];
        $sql[$key]= $value;
        return $this->transaction($sql);
    }
    public function delete($id,$accound_id){
        $ip = parent::getIp();
        $ENABLED = 'TRUE';
        $c = \DBConn::getTableNameFor('crons');
        $key ='DELETE FROM `'.$c.'` WHERE `id`=:id AND `accound_id`=:accound_id';//
        $value = [':id'=>$id,':accound_id'=>$accound_id];
        $sql[$key]= $value;
        return $this->transaction($sql);
    }
    public function Update($id,$url,$info,$STATUS, $REPETITION,$ENABLED,$LOGIT,$priority){
        $c = \DBConn::getTableNameFor('crons');
        $key ='UPDATE `'.$c.'` SET `url`=:url,`info`=:info, `STATUS`=:STATUS, `REPETITION`=:REPETITION,'.
               '`ENABLED`=:ENABLED,`LOGIT`=:LOGIT, `priority`=:priority  where id=:id';
        $value = [':url'=>$url,
        ':info'=>$info,
        ':STATUS'=>$STATUS,
        ':REPETITION'=>$REPETITION,
        ':ENABLED'=>$ENABLED,
        ':LOGIT'=>$LOGIT,
        ':priority'=>$priority,
        ':id'=>$id,
        ];
        $sql[$key]= $value;
        return $this->transaction($sql);
    }

}
?>
 
Ik heb gekeken naar cronjob alternatieven bij andere websites. Heb een gratis oplossing gevonden (met beperkingen, maar voldoende voor mijn doel)
Heb er een script bij gemaakt dat elke dag wordt herhaald, en voor zo ver ik kan ziet werkt het nu goed. Bedankt voor alle reacties.

Over de vraag waarom ik op een shared hosting zit, de website is puur hobbymatig opgericht en wordt door enkele gebruikers gebruikt.
 
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan