I don’t know how to search the net for the answer and I’m not sure how to explain the problem, so I’m sorry if it’s not clear or if it’s been asked before.
Here’s the deal: I need to show some items which have different statuses (there’s “unanswered”, “in discussion” and “answered”). What’s happening now is that the unanswered questions are being shown, the correct text is being shown for the questions that are in discussion, but the text for the question that are answered is the same as the “in discussion”. When one of the questions is moved from “unanswered” to “in discussion”, the correct text is being show for the “answered” questions. When there are no “unanswered” questions, the text is correct for that item. But the other items are getting the same text as the “unanswered” and the questions that should be shown in “in discussion” aren’t visible.
Does someone know what I can do to fix this? I'll put some code below. Thanks!!!
overzicht.php
<?php
session_start();
if(!isset($_SESSION['views']))
{
header('Location: index.php');
}
else
{
$feedback = "";
try
{
include_once('classes/question.class.php');
$oQuestion = new Question();
$oQuestionsUnanswered = $oQuestion->getQuestionsUnanswered();
$oQuestionsInDiscussion = $oQuestion->getQuestionsInDiscussion();
$oQuestionsAnswered = $oQuestion->getQuestionsAnswered();
}
catch(Exception $e)
{
$feedback = $e->getMessage();
}
}
?>
To show the different items (this is repeated twice for the other 2 statuses, with other variables e.g $oQuestionsAnswered):
<h3>Vragen onbeantwoord:</h3>
<div id="questionUnanswered">
<?php
if(isset($oQuestionsUnanswered))
{
$unanswered_details = "";
while($arr_unanswered = mysqli_fetch_array($oQuestionsUnanswered))
{
$unanswered_details .= "<div class='head'>";
$unanswered_details .= "<div class='titel'>";
$unanswered_details .= "<a href='full_topic.php?id=".$arr_unanswered['bericht_id']."'>".$arr_unanswered['bericht_titel']."</a></div>";
$unanswered_details .= "<div class='datum'>" . $arr_unanswered['bericht_datum'] . "</div></div>";
}
echo $unanswered_details;
}
else
{
echo $feedback;
}
?>
</div>
question.class.php (this is also repeated for the other 2)
public function getQuestionsUnanswered()
{
include('connection.class.php');
$sql = "SELECT *
FROM tblbericht
WHERE fk_status_id = 3;";
$result = $conn->query($sql);
if($result->num_rows!=0)
{
return $result;
}
else
{
throw new Exception("Er zijn momenteel nog geen onbeantwoorde vragen");
}
mysqli_close($conn);
}
IMO you make a big mistake, you split the query moment from the fetch moment, so you can create an array of question objects, than you use it inside the page.
Here's a draft of your code adapted:
public function getQuestionsUnanswered()
{
include('connection.class.php');
$sql = "SELECT *
FROM tblbericht
WHERE fk_status_id = 3;";
$result = $conn->query($sql);
$_rv =array()
if($result->num_rows!=0)
{
while($arr = mysqli_fetch_array($result))
{
$_rv[] = new QuestionBean($arr);
}
}
else
{
throw new Exception("Er zijn momenteel nog geen onbeantwoorde vragen");
}
mysqli_close($conn);
return $_rv
}
Then
<h3>Vragen onbeantwoord:</h3>
<div id="questionUnanswered">
<?php
if(count($oQuestionsUnanswered))
{
$unanswered_details = "";
foreach( $oQuestionsUnanswered as $bean)
{
$unanswered_details .= "<div class='head'>";
$unanswered_details .= "<div class='titel'>";
$unanswered_details .= "<a href='full_topic.php?id=".$bean->bericht_id."'>".$bean->bericht_titel."</a></div>";
$unanswered_details .= "<div class='datum'>" . $bean->bericht_datum . "</div></div>";
}
echo $unanswered_details;
}
else
{
echo $feedback;
}
?>
</div>
Of course you can optimize it using 1 class for all kind of question and 1 function using the paramiter to select wich kind of question you need.
The type of question will be a parameter of QuestionBean.
QuestionBean is a Bean :)
As bean I mean a "simple" data object where each attributes has a getter and setter OR is public.
I use the __constructor as initializer with a function called populate:
class simpleBean{
public $id;
public function __construct($params){
// some logic as need
}
// simple populate
public function populate($params){
$valid = get_class_vars ( self );
foreach($params as $k => $v){
if(!isset($valid[$k]){
// if this key has no attrib matchig I skip it
continue;
}
$this->$k = $v;
}
}
}
class QuestionBean extend simpleBean{
public $attr1;
public function __construct($params){
// may be I've some common logic in parent
parent::__construc($params);
//
$this->populate($params);
}
}
Now after the
while($arr = mysqli_fetch_array($result))
{
$_rv[] = new QuestionBean($arr);
}
you will have an array ($rv) of beans, each bean is a single result row of your query, but it's an object, that's much better than a stupid array.
Related
I am in the process of turning my standard PHP project into something built on Symfony2. One part I have is this function
function viewAvailability(){
$db = Database::get();
$active = "Active";
// Fetch all the active alert IDs.
$idListSql = $db->prepare("SELECT DISTINCT id
FROM availability_alert
WHERE alert_status = :active");
$idListSql->bindParam(':active', $active);
$idListSql->execute();
$alerts = array();
// Go through each ID.
while ($idListRow = $idListSql->fetch(PDO::FETCH_ASSOC)) {
$alertId = (int)$idListRow["id"];
// Create the first dimension of the array, using the alert ID as the key.
$alerts[$alertId] = array();
// Fetch all the availability values for this alert.
$availabilitySql = $db->prepare("
SELECT availability, last_updated, class_letter, alert_pseudo, flight_number
FROM availability_alert_availability
WHERE availability_alert_id = {$alertId}
ORDER by class_letter, last_updated");
$availabilitySql->execute();
// Go through each availability result.
while ($aRow = $availabilitySql->fetch(PDO::FETCH_ASSOC)) {
// Fetch the date and hour for this availability row as a string.
$dateString = new DateTime($aRow["last_updated"]);
$dateString = $dateString->format('d M Y H:00');
// Create the second dimension of the array, using the alert pseudo as the key.
if (empty($alerts[$alertId][$aRow["alert_pseudo"]])) {
$alerts[$alertId][$aRow["alert_pseudo"]] = array();
}
// Create the third dimension of the array, using the flight number as the key.
if (empty($alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]])) {
$alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]] = array();
}
// Create the fourth dimension of the array, using the date string as the key.
if (empty($alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]][$dateString])) {
$alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]][$dateString] = array();
}
// Create the fifth dimension of the array, using the class letter as a key, and the
// availability value as the value.
$alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]][$dateString][$aRow["class_letter"]] = $aRow["availability"];
}
}
}
This is only part of the function, I then go onto a lot of loops to output the data in a table. Anyways, I have moved my database calls above into my Entities custom repository (using DQL instead).
I then do most of the above working in my controller
public function availabilityAction()
{
$em = $this->getDoctrine()->getEntityManager();
$alerts = $em->getRepository('NickAlertBundle:AvailabilityAlert')->getActiveAlertIds();
$alertsArray = array();
if (!$alerts) {
throw $this->createNotFoundException('Unable to find Availability.');
}
foreach($alerts as $alert){
$alertId = (int)$alert['id'];
$alertsArray[$alertId] = array();
$allAvailability = $em->getRepository('NickAlertBundle:AvailabilityAlert')->getAlertAvailability($alertId);
foreach($allAvailability as $alertAvailability)
{
$dateString = $alertAvailability['lastUpdated'];
$dateString = $dateString->format('d M Y H:00');
if (empty($alerts[$alertId][$alertAvailability['alertPseudo']])) {
$alertsArray[$alertId][$alertAvailability['alertPseudo']] = array();
}
if (empty($alerts[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']])) {
$alertsArray[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']] = array();
}
if (empty($alerts[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']][$dateString])) {
$alertsArray[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']][$dateString] = array();
}
$alertsArray[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']][$dateString][$alertAvailability['classLetter']] = $alertAvailability['availability'];
}
}
return $this->render('NickAlertBundle:Page:availability.html.twig', array(
'alertsArray' => $alertsArray,
));
}
Now it is a lot neater, but I feel there is too much going on in my controller (not sure if this is good or not). The other problem is that I am then passing this filled up array I have to my view. Now I have a complex table layout to create from this array, and I really dont think it should be the job of the view to do this. As an example, this is part of the code I would need to convert within the view
if (!empty($pseudos)) {
foreach ($pseudos as $pseudo => $flights) {
foreach ($flights as $flight => $dates) {
$firstDate = array_pop(array_keys($dates));
echo '<div class="availability_table_container">';
echo "<table class='availability_table'>";
echo "<tr>";
if ($i == 0) {
echo "<th></th>";
}
echo "<th class='pseudo-header'>{$flight}</th>";
echo "</tr>";
echo "<tr>";
foreach (array_keys($dates[$firstDate]) as $classLetter) {
if ($j == 0) {
echo "<th></th>";
}
$j++;
echo "<th class='class-header'>{$classLetter}</th>";
}
echo "</tr>";
foreach ($dates as $date => $classes) {
echo "<tr>";
if ($i == 0) {
echo "<td class='time_row'>{$date}</td>";
}
foreach ($classes as $classLetter => $availability) {
if ($availability >= 0) {
$className = $availability > 0 ? "green" : "red";
}
if ($availability == "." || $availability == "-") {
$className = "purple";
}
echo "<td class='number_row {$className}'>{$availability}</td>";
}
echo "</tr>";
}
$i++;
echo "</table>";
echo "</div>";
}
}
}
So what's the best way to handle this code? I think I am right in not allowing my view to handle the above code, but then where should I do it?
Any advice on the design is appreciated.
I have a select query and then another select query but for another table. I need to run the first query, then if it finds something, show a table with a foreach loop. And then, a second query run and select another table with a foreach loop too.
This is my DB class to run my DB :
class DB {
private static $_instance = null;
private $_pdo,
$_query,
$_error = false,
$_count = 0;
public $_results;
private function __construct() {
try {
$this->_pdo = new PDO(...);
} catch(PDOException $e) {
die($e->getMessage());
}
}
public static function getInstance() {
if(!isset(self::$_instance)) {
self::$_instance = new DB();
}
return self::$_instance;
}
public function query($sql, $params = array()) {
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)) {
$x = 1;
if(count($params)) {
foreach($params as $param) {
$this->_query->bindValue($x, $param);
$x++;
}
}
if($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
} else {
$this->_error = true;
}
}
return $this;
}
Then, on a page I have this following :
<?php if ($st = DB::getInstance()->query("SELECT * FROM resum WHERE form_id = ? ORDER by date DESC", array(Input::get('formID')))) {
if ($st->count()) { ?>
<div id="topSeparateurClient">
<div>Date</div>
<div>Concessionnaire</div>
<div>Client</div>
<div>Voiture</div>
<div>Prix</div>
<div>Statut</div>
</div>
<div style="clear:both;"></div>
<?php
foreach($st->_results as $result) {
echo "<div class=\"clientGenInfos\">
<div><b>".substr($result->date, 0, 10)."</b> / ".substr($result->date, 10)."</div>
<div>".$result->concessionnaire."</div>
<div>".$result->client."</div>
<div>".$result->voiture."</div>
<div>".$result->prix."</div>";
if ($result->statut == 'En Attente') {
echo '<div class="enAttente"><span>En Attente</span></div>';
} else if ($result->statut == 'Accepter') {
echo '<div class="accepter"><span>Accepter</span></div>';
} else if ($result->statut == 'Refuser') {
echo '<div class="refuser"><span>Refuser</span></div>';
}
echo " </div>
";
}
} else {
echo '<div class="aucuneDemande">Nothing from now.</div>';
}
}
?>
Then a second block, almost identical but with another table name in his query. The problem now is that my second table have the same values as the first one..I am stuck here, reading stuff on the net and nothing about this situation. I am still new to PDO object! please help!
EDIT ---
This is my second block..
<?php
if ($st = DB::getInstance()->query("SELECT * FROM users WHERE users.group = 3 ORDER by date DESC")) {
if ($st->count()) { ?>
<div id="topSeparateurClientConc">
<div>Prénom et Nom</div>
<div>Adresse</div>
<div>Nom d'utilisateur</div>
<div>Date d'inscription</div>
<div>Demandes reçues</div>
</div>
<div style="clear:both;"></div>
<?php
foreach($st->_results as $result2) {
echo "<div class=\"clientGenInfosConc\">
<div>".$result2->name."</div>
<div>".$result2->adresse."</div>
<div>".$result2->username."</div>
<div><b>".substr($result2->joined, 0, 10)."</b> / ".substr($result2->joined, 10)."</div>
<div>".$result2->concessionnaire."</div>
</div>";
}
} else {
echo '<div class="aucuneDemande">Aucune demande transférable en ce moment</div>';
}
}
?>
Do not write your own PDO wrapper. Period.
PDO is already a wrapper. Written by the professionals. It has some drawbacks, but at least it has no harmful features which newbie programmers introduce in hundreds.
If you want static method to get instance - all right, have it. But leave the rest for raw PDO. Saving yourself one function call doesn't worth struggling against fallacies of your own wrapper.
Do not save on calls at all! Look what are you doing:
<?php if ($st = DB::getInstance()->query("SELECT * FROM resum WHERE form_id = ? ORDER by date DESC", array(Input::get('formID'))))
It cannot be even read without scrolling. Are you fined for every extra line or what?
This one single line contains almost dozen operators!
This is called "write-only" style.
You are saving yourself a linefeed to write faster, but when it come to reading, you'll run here, crying "read my code for me!".
Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.
Especially if it's you who have to maintain. Look:
<?php
$sql = "SELECT * FROM resum WHERE form_id = ? ORDER by date DESC";
$st = DB::getInstance()->query($sql, array(Input::get('formID')));
if ($st)
One can read and comprehend it. And noone died for splitting this call in four lines. Now add a couple:
$sql = "SELECT * FROM resum WHERE form_id = ? ORDER by date DESC";
$st = DB::getInstance()->prepare($sql);
$st->execute(array(Input::get('formID')));
$data = $st->fetchAll();
if ($data)
assuming getInstance() returns raw PDO instance. And your code will be perfectly fine working.
All right, I can understand a programmer's desire to avoid repetitions. Here is a solution that solves this problem without drawbacks:
$sql = "SELECT * FROM resum WHERE form_id = ? ORDER by date DESC";
$data = DB::prepare($sql)->execute(array(Input::get('formID')))->fetchAll();
And quit that idea of writing SQL calls right in the template. Fetch all your data first and then include a file with markup.
<?php if ($data): ?>
<div id="topSeparateurClientConc">
<div>Prénom et Nom</div>
<div>Adresse</div>
<div>Nom d'utilisateur</div>
<div>Date d'inscription</div>
<div>Demandes reçues</div>
</div>
<div style="clear:both;"></div>
<?php foreach($data as $result2): ?>
<div class="clientGenInfosConc">
I have a database with lots of courses in for example, breakfast_cereal, breakfast_toast, lunch_salad, lunch_main etc etc
Im using this to put the data they enter into a variable containing there results, for example:
breakfast_toast = Wholemeal;Brown;50/50;
and
breakfast_hotdrinks = Tea;Coffee;Milk;
This is the script im using to gather that information:
if(!empty($_POST['toast_selection'])) {
foreach($_POST['toast_selection'] as $toast) {
$toast = trim($toast);
if(!empty($toast)) {
$toastchoices .= "$toast;";
}
}
}
This works absolutely fine, But i have about a lot of entries to collect and if they add more to the database i want them to automatically gather.
I had a go at trying to think of a way but i just can't figure it out, This is what i tried:
All the inputs are called the same as the $course_menuname, for example breakfast_cereal[]
$query = "SELECT * FROM course";
$result = mysql_query($query);
while($row = mysql_fetch_array($result))
{
$course_menuname = $row['course_menuname']; #E.G breakfast_cereal, breakfast_toast, lunch_main
$course_item = $row['course_jsname']; #E.G cereal, toast, jacketpotato
$postResults = $_POST[''.$course_menuname .''];
if(!empty($postResults)) {
echo $postResults."<br />";
foreach($postResults as $course_item) {
$course_item = trim($course_item);
if(!empty($course_item)) {
$course_item1 .= "$course_item;";
}
}
}
echo $course_item1."<br />";
}
This is what the end result should look for
if(!empty($_POST['toast'])) {
foreach($_POST['toast'] as $toast) {
$toast = trim($toast);
if(!empty($toast)) {
$toastchoices .= "$toast;";
}
}
}
if(!empty($_POST['toastextra_selection'])) {
#Gather Toast EXTRAs Choices
foreach($_POST['toastextra_selection'] as $toastextra) {
$toastextra = trim($toastextra);
if(!empty($toastextra)) {
$toastextrachoices .= "$toastextra;";
}
}
}
if(!empty($_POST['toastextra_selection'])) {
#Gather Cold Drinks Choices
foreach($_POST['colddrinks_selection'] as $colddrinks) {
$colddrinks = trim($colddrinks);
if(!empty($colddrinks)) {
$colddrinkschoices .= "$colddrinks;";
}
}
}
if(!empty($_POST['hotdrinks_selection'])) {
#Gather Hot Drinks Choices
foreach($_POST['hotdrinks_selection'] as $hotdrinks) {
$hotdrinks = trim($hotdrinks);
if(!empty($hotdrinks)) {
$hotdrinkschoices .= "$hotdrinks;";
}
}
}
First of all you should not use the mysql_* functions anymore. These functions are marked as deprecated. Alternativly you can use PDO or the mysqli_* functions.
I guess group change is what you need. Let 's start with a simple example.
try {
$data = array();
$pdo = new PDO(...);
foreach ($pdo->query("SELECT * FROM course") as $row) {
if (!isset($data[$row['course_menuname'])) {
$data[$row['course_menuname']] = array();
}
if (!empty($row['course_item'] && in_array($row['course_item'], $_POST[$row['course_menuname'])) {
$data[$row['course_menuname'][] = $row['course_item'];
}
}
} catch (PDOException $e) {
// error handling
}
// Output all choices by menuname
foreach ($data as $key => $value) {
echo "Choices for " . $key . "\n";
echo implode(";", $value) . "\n";
}
I am quite new to OOPS and Zend. I am converting a part of web app code to Zend framework, I can't post all the code in here coz its quite lengthy. I created a model as in the code below(I can post only two functions) and I want to access the variables inside the functions from the controller and then print them out in HTML tables(I guess I will have to use "views" for that", below is my model:
public function getVenueTypes()
{
$poiTypes = array();
if($this->_cache)
{
$key = $this->getCacheKey()."poiTypes_stats:{$this->language}";
}
if(!$poiTypes)
{
$sql = "SELECT poi_type_id, poi_type_name_".$this->language."
AS
poi_type_name
FROM
poi_types
ORDER BY
poi_type_name_".$this->language." ASC";
$result = mysql_query($sql);
if(!$result)
{
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= "Whole query: \n\n$sql\n";
die($message);
}
while($row = mysql_fetch_array($result))
{
$poiTypes[] = array('id' => $row['poi_type_id'] ,'name' => $row['poi_type_name']);
}
print_r($poiTypes);
if ($this->_cache)
{
$this->_cache->save($key, $poiTypes);
}
}
foreach($poiTypes as $poiType)
{
$count_type = null;
if($this->_cache)
{
$key = $this->getCacheKey()."poiTypeCount:{$poiType['id']}:{$this->metro_id}";
$count_type = $this->_cache->load($key);
}
if(!$count_type)
{
$sql = "SELECT COUNT(*) FROM
poi
WHERE
find_in_set('{$poiType['id']}', poi_type_id_array)
AND poi_status = 1 AND poi_address_prefecture_id = '$this->metro_id'";
$result = mysql_query($sql) or die(mysql_error());
}
if(!$result)
{
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= "Whole query: \n\n$sql\n";
die($message);
}
while($count = mysql_fetch_array($result))
{
$count_type[$poiType['id']][$this->metro_id] = $count['COUNT(*)'];
}
if($this->_cache)
{
$this->_cache->save($key, $count_type);
}
}
}
Any help is Highly appreciated, I hope I am being clear enough and thanks in advance.
I'm noy sure if this will help you, but you have several options to access those values.
Option 1: return an array with the variables you need
return array($myVar1, $myVar2, ..., $myVarN);
Option 2 (less modular): create the html string inside that function and then echo or return the string.
Im assuming that you have a basic knowledge of Zend
The basic idea of Zend framework is the link between controller ,models and view
Your model file,BlaBla.php
Class Namespace_models_BlaBla extends Zend_Db_Table_Abstract{
public function foo(){
return 'hello world';
}
}
Your controller say BarController and an action say test
class BarController extends extends Zend_Controller_Action{
public function testAction(){
$class = new Namespace_models_BlaBla();
$this->view->string = $class->foo();
}
}
Your html side // test.phtml
<?php echo $this->string; ?> /**this will output hello world **/
I'm trying to display all the values from a specific column created by my Wordpress plugin (specifically, the ID's). Here is the code I have managed to use to display the column names, but I cannot get it to just display all the ID's. Here is the code:
function test() {
global $wpdb;
global $table_name;
$testing = $wpdb->get_col_info('name', 0);
foreach ($testing as $test) {
echo $test;
}
}
And here you can see the output:
www.matthewruddy.com/premiumslider
Can anyone help me out?
It seems you want data instead of column information. So you need to another function.
$testing = $wpdb->get_results("SELECT id FROM mytable")
foreach ($testing as $test) {
echo $test->id
}
EDIT:
OK, how about this one:
$wpdb->show_errors();
echo 'Listing from table: $table_name<br>';
$ids = $wpdb->get_col($wpdb->prepare("SELECT id FROM %s", $table_name));
if ($ids) {
echo 'printing results:<br>';
foreach($ids as $id) {
echo $id;
}
} else {
echo 'no results or error<br>';
echo 'error: ' . $wpdb->print_error();
}
$wpdb->hide_errors();
If this doesn't help you either to get your ID's or to figure out what the error is, I am lost.
Might be a little late for this question, but I think it is still relevant to todays WordPress world and also a situation I ran into creating my own plugin.
So for anyone else, this worked for me. The OP almost had it. However, $wpdb->get_col_info() relies on a cache result for its results so a $wpdb->get_results or get_row or query needed to be called first. :)
I also liked littlegreen's error handling.
function test() {
global $wpdb, $table_name;
$wpdb->show_errors();
$return = 'Listing from table: '.$table_name.'';
$results = $wpdb->get_results("SELECT * FROM ".$table_name);
$nameCols = $wpdb->get_col_info('name');
if (is_array($nameCols)) {
$return .= 'printing results:';
foreach($nameCols as $name) {
$return .= ' '.$name;
}
} else {
$return .= 'no results or error'.
'error: ' . $wpdb->print_error();
}
$wpdb->hide_errors();
}