php-mysql question about getting multiple verses
ANSWER FOUND: I am reading all and deciding, THANK YOU SOO MUCH hahaha :D I <3 stackoverflow
I apologize for the vagueness of this question and the lack of research, but I really had no idea how to google this question开发者_开发问答.
I am passing a bible verse and bible chapter into a page that takes it and pulls the verse from the bible db likes this
?book=Genesis&chapter_number=1&verse_number=1
But what I want to be able to do is send in multiple verses separated by a "-"
like this:
?book=Genesis&chapter_number=1&verse_number=1-2
I don't really know how this would work. Any ideas?
This works. It allows you to give a range of verses like 1,3,4-10
. It'll return the whole chapter if no specific verses are given.
// Get the book and chapter
$book = isset($_GET['book'])?(string)$_GET['book']:'';
$chapter = isset($_GET['chapter'])?(string)$_GET['chapter']:'';
// Make sure you escape the string to prevent SQL injection
$book = mysql_real_escape_string($book);
$chapter = mysql_real_escape_string($chapter);
// Get the verses as a string.
$verses = isset($_GET['verses'])?trim($_GET['verses']):'';
if ($verses ==='') {
// If no verses are given, TRUE will trick the database
// into returning all verses for the given book.
$verseWhere = 'TRUE';
} else {
// Split it on the commas
$verseRanges = explode(',', $verses);
$verseConditions = array();
// Split each value on '-', if any
foreach($verseRanges as $verseRange) {
$verseRange = explode('-', $verseRange);
// Build a condition
if (count($verseRange) === 1) {
$verseConditions[] = "verse = ".(int)$verseRange[0];
} else {
$verseConditions[] = "verse BETWEEN ".(int)$verseRange[0]." AND ".(int)$verseRange[1];
}
}
// Implode the array to build a list of conditions
$verseWhere = "(".implode(' OR ', $verseConditions).")";
}
// Create the SQL statement
$query = "
SELECT
*
FROM
Bible
WHERE
book = '$book' AND
chapter = '$chapter' AND
$verseWhere";
[edit] Made some minor changes, removed the typo's and actually run the script to test it. :)
Send request as
?book=Genesis&verse_number[]=1&verse_number[]=2&verse_number[]=3=10
Server will receive this as
$_GET = array(
'book' => 'Genesis',
'verse_number' => array(
'1',
'2',
'3-10'
)
)
$verses = array();
foreach($_GET['verse_number'] as $item) {
$item = explode('-', $item);
if(isset($item[1])) {
for($i=(int)$item[0];$i<=(int)$item[1];$i++)
$verses[] = $item[$i];
} else {
$verses[] = $item[0];
}
}
My better (imho) version of GolezTrol's script. Defaults to Genesis, chapter 1, verse 1 if no information is provided in the URL. Also fixed some syntax errors/misspellings in his script. Also, he forgot the book. ;) Finally, removed excess type casting, and used escaping where necessary:
$book = empty($_GET['book']) ? 'Genesis' : $_GET['book'];
$chapter = empty($_GET['chapter']) ? '1' : $_GET['chapter'];
$verses = empty($_GET['verses']) ? '1' : $_GET['verses'];
$book = mysql_real_escape_string($book);
$chapter = mysql_real_escape_string($chapter);
$verseRanges = explode(',', $verses);
$vC = array();
foreach($verseRanges as $verseRange) {
$vR = explode('-', $verseRange);
foreach ($vR as &$value) {
$value = mysql_real_escape_string($value);
}
$vC[] = count($vR) === 1
? 'verse = ' . $vR[0]
: 'verse BETWEEN ' . implode(' AND ', $vR);
}
$query = "SELECT * FROM Bible WHERE chapter = '" . $chapter . "' ";
$query .= "AND book = '" . $book . "' ";
$query .= 'AND (' . implode(' OR ', $vC) . ')';
Using type casting in lieu of escaping makes your code less readable/understandable. Always code for readability in the future. Also, $_GET
values are already strings.
精彩评论