PHP Funktion zeitgesteuert ausführen?

PHP, Ajax, CSS, HTML, Javascript
Eben für die wirklich Harten, die alles selber machen.
Antworten
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

PHP Funktion zeitgesteuert ausführen?

Beitrag von Dungeonwatcher »

Hi! :cool:

Ich bräuchte mal wieder eine Idee oder einen "Zaunpfahl" an den Kopf geworfen. ;)

Ich möchte per PHP an jedem 1. des Monats um 00:00 Uhr den Spielstand des Spiels Knuffel zurücksetzen. Dieser Befehl dafür sieht so aus:

Code: Alles auswählen

$sql = "UPDATE " . $knuffel_table ." SET score='0', played='0', average='0' ";
Der Wunsch dies wirklich zeitgesteuert um 00:00 Uhr auszuführen dürfte wohl nur per Cronjob zu erledigen sein. Das mag ich aber nicht wirklich.

Andererseits müsste es doch reichen, wenn der erste User im Monat das Spiel aufruft diese Aktion auslöst. Nur wie müsste das ganze aussehen?

Bye
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Das ist einfacher, wie es sich anhört.

Also:
In der Download MOD habe ich Resets z. B. so gelöst, in dem ich in einem Feld in irgendeiner Tabelle (hier könnte man z. B. die Board-Config nehmen, deren Werte eh schon zentral bereit stehen) das Datum der letzten Aktualisierung einträgt und damit prüft, welcher Monat zuletzt resettet wurde.

Für den Anfang dann eine 0 eintragen (für den ersten Reset), der Rest würde dann automatisch gesetzt. Dabei solltest Du den Code also erst dann einfügen, wenn noch kein Reset in dem Monat gelaufen ist!

Dabei käme zunächst diese SQL-Anweisung für zum Tragen, um den Reset-Status überhaupt festhalten zu können:

Code: Alles auswählen

INSERT INTO phpbb_config (config_name, config_value) VALUES ('knuffel_reset', '0');
Und nun muss (am besten in die includes/page_header.php) das Script zum Resetten ins Forum. Könnte man so machen:

Code: Alles auswählen

		$knuffel_reset_month = create_date('Ym', $board_config['knuffel_reset'], $board_config['board_timezone']);
		$current_time = time();
		$current_month = create_date('Ym', $current_time, $board_config['board_timezone']);

		if ($knuffel_reset_month < $current_month)
		{
			// Reset Knuffel Scores
			$sql = "UPDATE " . $knuffel_table ." SET
				score = '0', played = '0', average = '0'";
			$db->sql_query($sql);

			// Update last resetted month timestamp
			$sql = "UPDATE " . CONFIG_TABLE . " SET
				config_value = '$current_time'
				WHERE config_name = 'knuffel_reset'";
			$db->sql_query($sql);
		}
Damit würde der User, der als allererstes im neuen Monat Dein Forum betritt, den Knuffel-Reset automatisch auslösen und ab dann für den Rest des Monats nicht mehr...

Den Wink mit dem Zaunpfahl schenke ich mir, da man sowas nicht sofort wissen kann. Ich hatte damals auch eine Weile gebraucht, das in der Download MOD einzufügen...
Zuletzt geändert von oxpus am So 01.Mär, 2009 10:36, insgesamt 1-mal geändert.
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

Beitrag von Dungeonwatcher »

[quote="oxpus";p="88245"]Das ist einfacher, wie es sich anhört.[/quote]

Hmmm, das sagst du. ^6

Ich habe das jetzt mal so eingebaut. Wenn ich das jetzt richtig verstehe, dann wird in das Feld knuffel_reset die Zeit eingetragen wann resettet wurde und das im Unix Format. z.B. so 1233442800 für den 01.02.2009 00:00:00
Für den Anfang dann eine 0 eintragen (für den ersten Reset), der Rest würde dann automatisch gesetzt. Dabei solltest Du den Code also erst dann einfügen, wenn noch kein Reset in dem Monat gelaufen ist!
Hmmm, wie meinst du das jetzt? Da ich heute früh händisch resettet habe ist jetzt der Spielstand natürlich auf Null gesetzt.
Damit würde der User, der als allererstes im neuen Monat Dein Forum betritt, den Knuffel-Reset automatisch auslösen und ab dann für den Rest des Monats nicht mehr...
Ich harre geduldig auf den kommenden 1. März.
Den Wink mit dem Zaunpfahl schenke ich mir, da man sowas nicht sofort wissen kann. Ich hatte damals auch eine Weile gebraucht, das in der Download MOD einzufügen...
Danke.
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Ja, die Zeit ist auf die Sekunde genau, bewertet wird aber nur JahrMonat. Daher passt das schon.
Selsbtverständlich kannst Du auch einen Startwert im März eintragen, dann wird erst im April das nächste Mal aktualisiert.
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

Beitrag von Dungeonwatcher »

O.k. Danke. :cool:

Moin! :cool:

Leider hat es nicht funktioniert. Das dürfte daran liegen, das unterschiedliche Zeitformate angegeben werden. Aktuell sieht es so aus:

Code: Alles auswählen

$knuffel_reset_month = create_date('Ym', $board_config['knuffel_reset'], $board_config['board_timezone'], 0);
ergibt: 200902

Code: Alles auswählen

$current_time = time();


ergibt die aktuelle Zeit im Unix Format

Code: Alles auswählen

$current_month = create_date('Ym', current_time, $board_config['board_timezone']);
ergibt: 197001

^6

Ich habe auf die Schnelle mal dies getestet:

Code: Alles auswählen

$knuffel_reset_month = create_date('Ym', $board_config['knuffel_reset'], $board_config['board_timezone'];
$current_time = time();
$current_month = date('Ym');

if ($knuffel_reset_month < $current_month)
{

Code: Alles auswählen

"$knuffel_reset_month";
ergibt dann: 200902

Code: Alles auswählen

echo "$current_time";
bleibt im Unixformat

Code: Alles auswählen

"$current_month";
ergibt aktuelles Datum im Ym Format: 200903

Nun funktioniert offenbar auch dies:

Code: Alles auswählen

if ($knuffel_reset_month < $current_month)
200902 < 200903

In die Tabelle wird aber weiterhin das Unixformat eingetragen, welches $knuffel_reset_month dann korrekt als Ym ausliest.

Nun sollte es hoffentlich stimmen. Ich harre auf den 1. April... ;)
Zuletzt geändert von Dungeonwatcher am So 01.Mär, 2009 07:41, insgesamt 1-mal geändert.
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Code: Alles auswählen

$current_month = create_date('Ym', current_time, $board_config['board_timezone']);
Hier habe ich ja auch noch einen Fehler drinnen:
"current_time" ist hier keine Variable, daher wird "0" angenommen.
Da muss ein $ davor, damit die Zeile so ausschaut:

Code: Alles auswählen

$current_month = create_date('Ym', $current_time, $board_config['board_timezone']);
Alles andere hättest Du Dir jetzt schenken können... Sorry :!:
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

Beitrag von Dungeonwatcher »

Hi! :cool:

Gleich geändert und per echo anzeigen lassen, jupp jetzt wird auch korrekt 200903 angezeigt. THNX

[quote="oxpus";p="88249"]Alles andere hättest Du Dir jetzt schenken können... Sorry :!:[/quote]

Ach wat, ab und zu selber grübeln und 'ne Lösung finden ist auch ganz schön. Und sooo falsch war meine ja wohl hoffentlich nicht. ;)

Bye

Nachtrag:

Ich will das o.g. Beispiel etwas erweitern um eine Aktion Quartalsweise am 01.01., 01.04., 01.06. und am 01.09. durchzuführen.

Dazu nutze ich ebenfalls einen Zeitstempel in der Tabelle phpbb_config (vault_loan_interests_time).

Code: Alles auswählen

	$vault_day = create_date('Ymd', $board_config['vault_loan_interests_time'], $board_config['board_timezone']);
	$vault_quartals = create_date('md', $board_config['vault_loan_interests_time'], $board_config['board_timezone']);
	$current_time = time();
	$current_day = create_date('Ymd', $current_time, $board_config['board_timezone']);
	$current_quartals = create_date('md', $current_time, $board_config['board_timezone']);
Das ganze soll dann so ausgewertet werden:

Code: Alles auswählen

if (($vault_quartals < ($current_quartals == "0101")) or ($vault_quartals < ($current_quartals == "0401")) or ($vault_quartals < ($current_quartals == "0601")) or ($vault_quartals < ($current_quartals == "0901")))
{
Kann das so funktionieren?
Zuletzt geändert von Dungeonwatcher am Sa 14.Mär, 2009 08:32, insgesamt 1-mal geändert.
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Ja, das sollte gehen.
Da sehe ich jetzt so keinen Fehler.
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

Beitrag von Dungeonwatcher »

Ok. Bleibt jetzt nur noch eines zu lösen.

Ich gehe zwar davon aus das das Forum täglich von irgendjemandem besucht wird, sei es ein User oder Gast. Damit wird dies dann regelmäßig ausgeführt. Nur was passiert wenn es an diesem Tag tatsächlich keinen gibt, der das Forum besucht? Dann stimmt zwar die erste Bedingung:

Code: Alles auswählen

($vault_quartals < $current_quartals )
aber die zweite nicht mehr:

Code: Alles auswählen

($current_quartals == "0101")
Wie kann ich sicherstellen, das dann trotsdem 1x das ganze ausgeführt wird?
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Man könnte auch den Monat definieren und diesen speichern.
Also den ersten Monat des betreffenden Quartals und dieses immer mit dem aktuellen Datum vergleichen.
Wäre vielleicht sicherer, als sich immer nur auf den ersten Tag im Quartal zu verlassen...
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

Beitrag von Dungeonwatcher »

Moin! :cool:

Leider funktioniert mein obiges Konstrukt nicht wirklich. :(

Eigentlich hätte es heute am 01.04. entsprechend Zinsen auszahlen müssen, was aber nicht geschah.

Code: Alles auswählen

$vault_general = vault_get_general_config();
$sql = "SELECT * FROM " . VAULT_GENERAL_TABLE ;
if(!$result = $db->sql_query($sql))
{
	message_die(CRITICAL_ERROR, "Could not query information in Vault General Table", "", __LINE__, __FILE__, $sql);
}

$vault_day = create_date('Ymd', $board_config['vault_loan_interests_time'], $board_config['board_timezone'], 0);
$vault_quartals = create_date('md', $board_config['vault_loan_interests_time'], $board_config['board_timezone'], 0);
$current_time = time();
$current_day = create_date('Ymd', $current_time, $board_config['board_timezone'], 0);
$current_quartals = create_date('md', $current_time, $board_config['board_timezone'], 0);

// Quartalsweises Auszahlen der Zinsen
if (($vault_quartals < ($current_quartals == "0101")) or ($vault_quartals < ($current_quartals == "0401")) or ($vault_quartals < ($current_quartals == "0701")) or ($vault_quartals < ($current_quartals == "1001")))
{
	echo "$vault_quartals   ";
	echo "$current_quartals";
}

# Zeitstempel setzen
//$sql = "UPDATE " . CONFIG_TABLE . " SET
//	config_value = '$current_time'
//	WHERE config_name = 'vault_loan_interests_time'";
//$db->sql_query($sql);
Die Zeile 15 funktioniert scheinbar so nicht. Setze ich die beiden Echo Befehle vor Zeile 14, werden aber die korrekten Werte angezeigt:

0331 0401

und dies

Code: Alles auswählen

($vault_quartals < ($current_quartals == "0401"))
hätte greifen müssen, da 0331 < 0401.

Noch verwirrender wird es, wenn ich dies sage:

Code: Alles auswählen

($vault_quartals == ($current_quartals == "0401"))
Dann werden die beiden Echos der Zeilen 17 und 18 ebenfalls angezeigt? Bei

Code: Alles auswählen

($vault_quartals > ($current_quartals == "0401"))
korrekterweise dann nicht mehr.

Wo ist hier mein groooßer Denkfehler? ^6

Bye
Zuletzt geändert von Dungeonwatcher am Mi 01.Apr, 2009 05:11, insgesamt 3-mal geändert.
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Hm, hier scheint der Stringvergleich nicht zu greifen.
Vielleicht wäre es besser, Monat und Tag als Zahl darzustellen?
Also z. B. die Zeile

Code: Alles auswählen

$vault_quartals = create_date('md', $board_config['vault_loan_interests_time'], $board_config['board_timezone'], 0); 
Daraus könnte man machen:

Code: Alles auswählen

$vault_quartals = create_date('z', $board_config['vault_loan_interests_time'], $board_config['board_timezone'], 0);
Dann käme da eine Zahl raus, die den Tag des Jahres definiert.
Hier müsste man nur dann noch die entsprechende Zahl für jeden 1. im neuen Quartal dagegen halten und der Vergleich sollte wieder klappen...
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

Beitrag von Dungeonwatcher »

Hi! :cool:

Ich hab deine Idee entsprechend angepasst. Anstelle von 0331 und 0401 gibt's dann 89 bzw. 90. Dann müsste die Bedingung wohl so aussehen:

Code: Alles auswählen

($vault_quartals < ($current_quartals == "90"))
Das funktioniert aber auch nicht. Was aber offenbar funktioniert ist dies:

Code: Alles auswählen

($vault_quartals < "0401")
oder eben

Code: Alles auswählen

($vault_quartals < "90")
D.h. ich kann mir dies sparen:

Code: Alles auswählen

($current_quartals == "0401")
und direkt mit dem Zahlenwert arbeiten. Das ganze sieht dann so aus:

Code: Alles auswählen

if (($vault_quartals < "0101") or ($vault_quartals < "0401") or ($vault_quartals < "0701") or ($vault_quartals < "1001"))
Aber auch das funktioniert so nicht.

Ich habe die Ursache für dieses Verhalten aber offenbar gefunden. Schuld an dieser Misere ist die führende Null bei der Quartalsanzeige. Mit 0401 etc. kommt ein Vergleich wohl nicht zurecht. D.h. ich muss das Jahr mit davor setzen. Das bringt insofern auch gleich eine Lösung für den 01. Januar mit, denn da kann die bisherige Bedingung so nicht zutreffen.
Das stelle ich mir so vor:

Code: Alles auswählen

$current_Year = create_date('Y', $current_time, $board_config['board_timezone'], 0);
Das ergibt das aktuelle Jahr. Wie müsste ich dann die Variable hier an die 0401 anfügen?

Code: Alles auswählen

($vault_quartals < "0401")
Dies funktioniert so nicht:

Code: Alles auswählen

($vault_quartals < "$current_Year .'0401')
denn es gibt ein Leerzeichen zwischen Jahreszahl und 0401. Also dachte ich an folgende Lösung:

Code: Alles auswählen

$current_Year = create_date('Y', $current_time, $board_config['board_timezone'], 0);
	
$quartals1 = $current_Year . '0401';
$quartals2 = $current_Year . '0701';
$quartals3 = $current_Year . '1001';
$quartals4 = $current_Year . '0101';

if (($vault_quartals < $quartals4) or ($vault_quartals < $quartals1) or ($vault_quartals < $quartals2) or ($vault_quartals < $quartals3))
Das ergibt dann dies: 20090331 < 20090401

Das funktioniert so aber auch nicht. ^6

Grundproblem scheint die ODER Verknüpfung dieser Bedingungen zu sein. Nehme ich z.B. nur eine Bedingung:

Code: Alles auswählen

if ($vault_quartals < $quartals1)
dann funktioniert es.
Zuletzt geändert von Dungeonwatcher am Mi 01.Apr, 2009 11:49, insgesamt 1-mal geändert.
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Wenn Du nur mit den Zählwerten gearbeitet hättest, käme das gleiche raus ;)
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

Beitrag von Dungeonwatcher »

[quote="oxpus";p="88339"]Wenn Du nur mit den Zählwerten gearbeitet hättest, käme das gleiche raus ;)[/quote]

Das stimmt wohl, nur funktioniert es in Kombination mit den vielen ODER Bedingungen trotzdem nicht. Sowie nach der ersten Bedingung eine ODER Bedingung dazu kommt, klappt es halt nicht mehr. Jede Bedingung alleine hingen tut was sie soll.

Was die Zahlen angeht haben diese den Nachteil, das Schaltjahre und der Jahreswechsel nicht sauber funktionieren.

Ich muss jetzt los zur Nachtschicht. Hoffentlich ist das größte Narrenhaus Berlin heute mal etwas ruhig, dann kann ich mir mal wieder mein PHP Buch reinziehen. Evtl. fällt mir ja dabei was passendes ein.

Bye
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Was die Zahlen angeht haben diese den Nachteil, das Schaltjahre und der Jahreswechsel nicht sauber funktionieren.
Doch, das klappt schon. 1 ist immer der 1.1. und ob man nun den 1.4 oder 2.4 hätte (Schaltjahr) macht den Kohl nicht wirklich Fett, oder?
Zumal man mit etwas Kniff auch das Schaltjahr noch herausfinden könnte ;)

Die Kette der ODER-Verknüpfungen muss man allerdings dann auch eher umdrehen oder teilen, sonst läuft man auch Gefahr, für den niedrigsten Wert (also ein Tag im ersten Quartal) auch alle Optionen auszulösen...

Hach, ist das immer so unlogisch logisch...
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Benutzeravatar
Dungeonwatcher
Beiträge: 1055
Registriert: Sa 19.Feb, 2005 01:16
Wohnort: Berlin
Kontaktdaten:

Beitrag von Dungeonwatcher »

Hi! :cool:

Ich muss nochmal nerven, denn ich bekomme es einfach nicht hin. ?4

[quote="oxpus";p="88343"]Die Kette der ODER-Verknüpfungen muss man allerdings dann auch eher umdrehen oder teilen, sonst läuft man auch Gefahr, für den niedrigsten Wert (also ein Tag im ersten Quartal) auch alle Optionen auszulösen...[/quote]

Genau das passiert auch. :(
Aktuell habe ich es immer noch so umgesetzt aber auskommentiert:

Code: Alles auswählen

{
	$vault_day = create_date('Ymd', $board_config['vault_loan_interests_time'], $board_config['board_timezone'], 0);
	$vault_quartals = create_date('Ymd', $board_config['vault_loan_interests_time'], $board_config['board_timezone'], 0);

	$current_time = time();
	$current_day = create_date('Ymd', $current_time, $board_config['board_timezone'], 0);
	$current_quartals = create_date('md', $current_time, $board_config['board_timezone'], 0);
	$current_Year = create_date('Y', $current_time, $board_config['board_timezone'], 0);
	
	$quartals1 = $current_Year . '0401';
	$quartals2 = $current_Year . '0701';
	$quartals3 = $current_Year . '1001';
	$quartals4 = $current_Year . '0101';	
	
	if (($vault_quartals < $quartals1) or ($vault_quartals < $quartals2) or ($vault_quartals < $quartals3) or ($vault_quartals < $quartals4))
	{
Bei dieser oder Verküpfung (Zeile 15) habe ich einfach keine Idee wie ich es anders umsetzen müsste, das immer nur eine dieser Bedingungen zutreffen kann. ^6
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Denk einfach mal logisch nach, was passiert, wenn du das 1., 2., 3., oder 4. Quartal hast.
Wird die Bedingung dann jeweils wahr oder falsch und wenn wahr, dann auch korrekterweise?
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Antworten