我有一个每天运行的小型PHP Cron作业,它从API获取文件并将其保存到静态文件中。
file_put_contents("api.json", fopen("http://example.com/api", 'r'));
此JSON的内容如下:
{
recipes: [
{
id: 30476,
title: "Selfmade Chicken Nuggets",
...
},
{...} ]
}
我的问题:我想创建“每日食谱”逻辑。
因此,我想每天创建一个包含食谱的额外数组。
在最好的情况下,我想要这样的东西:
步骤1:创建一个包含所有食谱的“剩余食谱阵列”
第2步::每天从剩余的食谱数组中获取3个食谱,并将它们放入某种“每日食谱”数组中
第3步:如果剩余的食谱数组为空或没有3个元素,请从食谱中重新填充
我的Javascript客户端中已经具有该逻辑:
let fullRecipeList = await this.appData.getRecipeList();
let recipesOfTheDay = await this.appData.getItem("recipesOfTheDay");
let recipesOfTheDayValidUntil = await this.appData.getItem(
"recipesOfTheDayValidUntil"
);
let remainingRecipes = await this.appData.getItem("remainingRecipes");
if (!remainingRecipes || remainingRecipes.length < 3) {
remainingRecipes = this.shuffleArray(fullRecipeList);
}
if (
recipesOfTheDay &&
moment(recipesOfTheDayValidUntil).isSame(new Date(), "day")
) {
this.recipeList = recipesOfTheDay;
} else {
recipesOfTheDay = remainingRecipes.splice(0, 3);
this.recipeList = recipesOfTheDay;
await this.appData.setItem("remainingRecipes", remainingRecipes);
await this.appData.setItem("recipesOfTheDay", recipesOfTheDay);
await this.appData.setItem(
"recipesOfTheDayValidUntil",
moment().startOf("day")
);
}
是否可以在服务器端cron作业中创建这种逻辑?
代码看起来如何?我对整个PHP世界都是陌生的:)
答案 0 :(得分:1)
有时候,如果您直接在php
中使用cron
,则环境会有所不同,并且文件可能存在问题:找不到文件可供读取,或者文件可以写在陌生的地方
我在cron作业中所做的就是直接使用wget
或类似实用程序来调用Web服务:
# every day at eight run recipes of the day
* 8 * * * wget -q -O /dev/null 'https://www.server.com/recipesOfTheDay.php'
您甚至可以使用localhost
作为服务器名称。
您的脚本然后可以保存到本地JSON文件或具有修改后内容的任何文件。
答案 1 :(得分:0)
像这样吗?
<?php
$totalRecipesPerDay = 3;
// Open remaining receipes. If the file does not exists, return an empty array
$remainingRecipes = file_exists('remaining_recipes.json') ? json_decode(file_get_contents('remaining_recipes.json'), true) : [];
// Check if atleast $totalRecipesPerDay are available
if (count($remainingRecipes) < $totalRecipesPerDay) {
// Insufficient receipes, getting it from the complete list
$remainingRecipes = json_decode(file_get_contents('all_recipes.json'), true);
// Shuffling results
shuffle($remainingRecipes);
}
$recipesOfTheDay = [];
for ($i = 0; $i < $totalRecipesPerDay; ++$i) {
// Extracting n times a recipe from my remaining list, and update it in the meantime
$recipesOfTheDay[] = array_shift($remainingRecipes);
}
// Save results :D
file_put_contents('remaining_recipes.json', json_encode($remainingRecipes));
file_put_contents('recipes_of_the_day.json', json_encode($recipesOfTheDay));
然后使用crontab -e
设置cronjob:
* * * * * php /var/www/your_project/file.php
以下说明:
https://www.ostechnix.com/wp-content/uploads/2018/05/cron-job-format-1.png
答案 2 :(得分:0)
未经测试。请参阅以下脚本注释。
if ( ! file_exists('remaining-recipes.json') // e.g. on first ever run of script
$reminingRecipeArray = renew_remaining_recipes_file();
}
else {
$reminingRecipeArray = json_decode(file_get_contents('remaining-recipes.json'), true);
if count($reminingRecipeArray) < 3 ) renew_remaining_file();
}
// equivalent to your javascript example
$recipesOfTheDayArray = array[];
shuffle($reminingRecipeArray);
for ($i=0; $i < 2; $i++) {
$recipesOfTheDayArray[i] = array_pop($reminingRecipeArray);
// n.b. pop gets/removes element from array end - see my answer
}
file_put_contents('recipes_of_the_day.json', json_encode($recipesOfTheDayArray));
file_put_contents('remaining_recipes.json', json_encode($reminingRecipeArray));
//----------------
//***Functions****
//----------------
function renew_remaining_recipes_file() {
if ( ! file_exists('allrecipes.json') ) {
get_all_recipes_file(); // remove surrounding "if" to always refresh via API whenever remaining list empty
}
$reminingRecipeArray = json_decode(file_get_contents('allrecipes.json'), true);
if (empty( $reminingRecipeArray) || count($reminingRecipeArray) < 3 ) { // on fail or empty array
email_and_exit('could not refresh remaining recipe list - maybe allrecipes file is not json');
}
return $reminingRecipeArray;
}
function get_all_recipes_file() {
// uses yor current code which I assume works
$allOK = file_put_contents("allrecipes.json", fopen("http://example.com/api", 'r'));
// $allOK is FALSE (0) on failure otherwise number of bytes in file
if ($allOK < 500) {
email_and_exit('Failed to create "allrecipes.json" or created file or too small for expected data');
}
}
DEFINE("TESTING", TRUE);
function email_and_exit($msg) {
if (TESTING) echo $msg; // additionally echo msg to screen when testing
mail(YOUR_EMAIL_ADDRESS, 'Recipe Error', $msg, 'From: yourpage@YOURSITE');
exit;
}
以上代码使用array_pop从剩余配方数组的末尾提取3个项目。如果您希望从数组的开头开始使用食谱,请使用数组_shift但效率较低的https://www.php.net/manual/en/function.array-pop.php#112946
您的访客可能在不同的时区,因此,如果他们在第二天(他们)隔天返回12小时,他们可能会收到相同的食谱。可以仅使用PHP解决此问题,但从回忆起,使用天气API时,如果不熟悉PHP,则可能会很棘手。您可以结合使用PHP和JS来创建和循环3(9?)每日配方条目(或3个带日期编号的文件)
PHP的天数;
$serverDay = idate('w', $timestamp); // day of week as integer (Sunday=0);
$dayafter = $intDay + 1;
$daybefore = $intDay - 1;
然后使用JavaScript调用中的getDay()中的数字告诉服务器应提供的日期。