Tabulate results of PHP MYSQL search using class-search.php - php

So I have a large database (120k rows) and I'm building a little web app to make it useful for the community (astronomy based stuff). I'm new to php and am looking for a little help.
I have a search.php file and a class-search.php file and at the moment the results look like this:
2 results found
Array
(
[count] => 2
[results] => Array
(
[0] => stdClass Object
(
[disc] => LOC 7
[fstdate] => 2016
[lstdate] => 2016
[lstpa] => 170
[lstsep] => 0.4
[stype] =>
[comp] => AB
[fstmag] => 13.80
[secmag] => 14.10
[dnum] =>
[rahour] => 05
[ramin] => 38
[rasec] => 48.04
[decdeg] => -02
[decmin] => 27
[decsec] => 14.2
)
[1] => stdClass Object
(
[disc] => LOC 7
[fstdate] => 2016
[lstdate] => 2016
[lstpa] => 284
[lstsep] => 7.5
[stype] =>
[comp] => AB,C
[fstmag] => 13.20
[secmag] => 16.60
[dnum] =>
[rahour] => 05
[ramin] => 38
[rasec] => 48.04
[decdeg] => -02
[decmin] => 27
[decsec] => 14.2
)
)
)
I'm looking to tabulate the results and I have got a rough idea what I'm doing but I'm not quite getting everything joined up - can anyone suggest anything please.
The key part of search.php looks like this: (Code may not be fully accurate as I've taken out some switches and ifs to reduce post length)
<?php
//Check if search data was submitted
if ( isset( $_GET['s'] ) ) {
// Include the search class
require_once( dirname( __FILE__ ) . '/class-search.php' );
// Instantiate a new instance of the search class
$search = new search();
// Store search term into a variable
$search_term = htmlspecialchars($_GET['s'], ENT_QUOTES);
// Send the search term to our search class and store the result
$search_results = $search->search($search_term);
}
?>
<!DOCTYPE html>
<html>
<head>
<title>WDSC search</title>
</head>
<body>
<h1>Search the WDSC</h1>
<div class="search-form">
<form action="" method="get">
<div class="form-field">
<label for="search-field">Search term</label>
<input type="search" name="s" placeholder="Enter your search term..." results="5" value="<?php echo $search_term; ?>">
<input type="submit" value="Search">
........
</form>
</div>
<?php if ( $search_results ) : ?>
<div class="results-count">
<p><?php echo $search_results['count']; ?> results found</p>
</div>
<div class="results-table">
<?php foreach ( $search_results['results'] as $search_result ) : ?>
<div class="result">
<p><?php echo $search_result->title; ?></p>
</div>
<?php endforeach; ?>
</div>
<div class="search-raw">
<pre><?php print_r($search_results); ?></pre>
</div>
<?php endif; ?>
</body>
</html>
and the key parts of class-search.php looks like this:
<?php
/**
* Performs a search
*
* This class is used to perform search functions in a MySQL database
*
*/
class search {
/**
* MySQLi connection
* #access private
* #var object
*/
private $mysqli;
/**
* Constructor
*
* This sets up the class
*/
public function __construct() {
// Connect to our database and store in $mysqli property
$this->connect();
}
/**
* Database connection
*
* This connects to our database
*/
private function connect() {
$this->mysqli = new mysqli( 'server', 'user', 'pass', 'db' );
}
/**
* Search routine
*
* Performs a search
*
* #param string $search_term The search term
*
* #return array/boolen $search_results Array of search results or false
*/
public function search($search_term) {
// Sanitize the search term to prevent injection attacks
$sanitized = $this->mysqli->real_escape_string($search_term);
// Define variable for search category from list selection
$cat = $_GET['category'];
// Run the query.
// Query for discoverer
$query = $this->mysqli->query("
SELECT disc, fstdate, lstdate, lstpa, lstsep, stype, comp, fstmag, secmag, dnum, rahour, ramin, rasec, decdeg, decmin, decsec
FROM WDS_CAT
WHERE $cat LIKE '{$sanitized}%'
");
}
// Check results
if ( ! $query->num_rows ) {
return false;
}
// Loop and fetch objects
while( $row = $query->fetch_object() ) {
$rows[] = $row;
}
// Build our return result
$search_results = array(
'count' => $query->num_rows,
'results' => $rows,
);
return $search_results;
}
}
endif;
?>
I've tried to link a table to the variable $search_results by means of
echo '<table border=1px>'; // opening table tag
echo'<th>Discoverer</th><th>First year observed</th><th>Last year observed</th><th>Last position angle</th><th>Last separation</th><th>Spectral type</th><th>Components</th><th>Primary Magnitude</th><th>Secondary magnitude</th><th>Durchmusterung number</th><th>Right ascension</th><th></th><th></th><th>Declination</th><th></th><th></th>'; //table headers
while($data = mysql_fetch_array($search_results))
{
// we are running a while loop to print all the rows in a table
echo'<tr>'; // printing table row
echo '<td>'.$data['disc'].'</td><td>'.$data['fstdate'].'</td><td>'.$data['lstdate'].'</td><td>'.$data['lstpa'].'</td><td>'.$data['lstsep'].'</td><td>'.$data['stype'].'</td><td>'.$data['comp'].'</td><td>'.$data['fstmag'].'</td><td>'.$data['secmag'].'</td><td>'.$data['dnum'].'</td><td>'.$data['ragiyr'].'</td><td>'.$data['ramin'].'</td><td>'.$data['rasec'].'</td><td>'.$data['decdeg'].'</td><td>'.$data['decmin'].'</td><td>'.$data['decsec'].'</td>'; // we are looping all data to be printed till last row in the table
echo'</tr>'; // closing table row
}
echo '</table>'; //closing table tag
?>
<?php endif; ?>
But no joy - can anyone suggest something please.
Thanks in advance

Assuming you're just trying to output the results in a HTML table...?
UPDATE:
foreach($search_results['results'] as $resultRow) {
var_dump($resultRow);
}
This should do the trick. You're returning the resultset already processed into your array so you just need to loop on that array and not call mysql_fetch_array() again
I would firstly add
var_dump($data);
exit();
right after
while($data = mysql_fetch_array($search_results))
{
to loop only once and see what each loop returns. It's probably only returning [count] and [results] arrays so you might need to loop again on [results] array. Review the PHP reference for mysql_fetch_array http://php.net/manual/en/function.mysql-fetch-array.php
e.g.
while($data = mysql_fetch_array($search_results))
{
if(is_array($data['results'])){
foreach($data['results'] as $resultRow) {
var_dump($resultRow);
}
}
Within the foreach loop you can add your HTML output as you have above
NOTE: All this is based on the assumption that mysql_fetch_array() returns the the data structure as per your first code snippet.
2 results found
Array
(
[count] => 2
[results] => Array
(
[0] => stdClass Object
(

Fixed!!
I eventually turned on my brain and worked out that the return from the dump was an object not an array, so I cast it to an array using $resultsArray = (array)$resultRow; and ran that into the table.
It's dirty, but this is now doing what I want. Thanks #JI-Web, I couldn't have done it without your help. I think I'm getting the hang of PHP now.
Onto pagination and pulling relevant data from 3rd party sources into a frame based on the results. I may be back for more help!

Related

PHP sessions - Get username from sessions stored in database

Since moving session handling over to the database, the $_SESSION array doesn't seem to hold any values which I think is how sessions behave in PHP once the implementation is moved to DB.
This is causing quite a headache for me now. I'm not able to access the username of the user logged in via the details stored in the DB.
Here's my implementation of a function to retrieve the details of a user from the DB.
public function getUser($id, $db) {
$dbobj->query("SELECT * FROM SESSION WHERE id = $id);
$result = $dbobj->res();
return $result['data']['use'];
}
$result holds the values int he following format
array(1) (
[0 => array(3) (
[id => (string) 3fgg67bbsd77bVVgh
[access => (string) 14567893546
[data => (string) luser|s:5"Marke";
)
)
I would like $temp to hold the value "Marke". How should I parse the resultest returned?
I'd appreciate any help please.
resultset() function might be not exist.
So you can use this code:
public function getSessionUserName($id, $dbobj) {
$lcid = $id;
$dbobj->query("SELECT * FROM SESSION WHERE id = :sessid");
$dbobj->bind(':sessid', $lcid);
// execute query
$dbobj->execute();
// Commented this line
//$result = $dbobj->resultset();
// Use fetch() method
$result = $dbobj->fetch();
if ($result) {
//$temp= $result['data']['luser'];
$temp= $result['luser']
return $temp;
}
}
$result will generate following type of output (Output will be based on fields ):
Array
(
[id] => 3fgg67bbsd77bVVgh
[0] => 3fgg67bbsd77bVVgh
[access] => 14567893546
[1] => 14567893546
[luser] => Marke
[2] => Marke
)

Grab more out multidimensional array to put in recursive foreach function

I am trying to learn more about multi-dimensional arrays along with recursive functions so as an exercise I have a threaded comments section. each comment (in the database) has an id, parent id (0 by default, but will be the id of the comment that it is in reply to), and content plus more.
I have followed a tutorial and come up with a half complete solution, however I can only grab a portion of the array's data with my current solution. I want to be able to grab the extra information such as 'authorId', 'commentDate' and everything I have tried thus far to do so has resulted in massive failure. Here is my code so far, the is the recursive function (within a class):
function makeList($parentId) {
// Need the main $comms array:
global $comms;
echo '<ul>'; // Start an unordered list.
// Loop through each subarray:
foreach ($parentId as $comm_id => $theCommName) {
// Display the comment:
echo "<li>".$theCommName;
// Check for sub comments:
if (isset($comms[$comm_id])) {
// Call this function again:
self::makeList($comms[$comm_id]);
}
echo '</li>'; // Complete the list item.
} // End of FOREACH loop.
echo '</ul>'; // Close the ordered list.
} // End of function.
and here is another function that will connect to the database to retrieve comments, and make use of the previous function:
function callCommentList($pid){
// Connect to the database:
$dbc = mysqli_connect(HOST_NAME, USERNAME, PASSWORD, DB_NAME);
// Retrieve all the comments from a particular post:
$q = 'SELECT id, parentId, content, authorId, postId, commentDate, approved FROM comments WHERE postId='.$pid.' AND approved=1 ORDER BY parentId, commentDate ASC';
$r = mysqli_query($dbc, $q);
// Initialize the storage array:
global $comms;
$comms = array();
// Loop through the results:
while (list($commsId, $commParentId, $theComm, $authorId, $postId, $commentDate, $approved) = mysqli_fetch_array($r, MYSQLI_NUM)) {
// Add to the array:
$comms[$commParentId][$commsId] = $theComm;
}
self::makeList($comms[0]);
}
and on another page I have created the instance of the class and called the method:
$post->callCommentList($post->getId())
Here is the result (the unordered list):
Ideally however, I would also like to get other information pulled from the database such as authorId etc and display it with the comment(and more). Any idea on how to go about doing that?
Ok well, I was going about storing items into the array wrong.
In my original code, I stored JUST the comment contents three levels deep, however I realised I could also store other things I needed three levels deeps (the author id + comment date), and did that as such:
while (list($commsId, $commParentId, $theComm, $authorId, $postId, $commentDate, $approved) = mysqli_fetch_array($r, MYSQLI_NUM)) {
// Add to the array the comment, the comment's author, the comment's date:
$comment = array($theComm, $authorId, $commentDate);
$comms[$commParentId][$commsId] = $comment;
}
which will equal this when the array is printed neatly:
Array
(
[0] => Array
(
[1] => Array
(
[0] => Comment One
[1] => 3
[2] => 2014-07-06 21:16:19
)
[4] => Array
(
[0] => Third Comment That does not reply to anything
[1] => 3
[2] => 2014-07-06 21:24:12
)
)
[1] => Array
(
[2] => Array
(
[0] => Comment That's In Response To Comment One
[1] => 3
[2] => 2014-07-06 21:17:03
)
)
)
so from there I could easily see that I could just grab the details via the index, so the revised recursive method is as follows:
function makeList($parentId) {
// Need the main $comms array:
global $comms;
echo '<ul>'; // Start an unordered list.
// Loop through each subarray:
foreach ($parentId as $comm_id => $theComm) {
// Display the item:
echo "<li>";
echo "<strong>Id:</strong> ".$comm_id."<br/>";
echo "<strong>The Comment</strong> : ".$theComm[0]."<br/>";
echo "<strong>Author Id:</strong> ".$theComm[1]."<br/>";
echo "<strong>Comment Date:</strong> ".$theComm[2];
// Check for comments:
if (isset($comms[$comm_id])) {
// Call this function again:
self::makeList($comms[$comm_id]);
}
echo '</li>'; // Complete the list item.
} // End of FOREACH loop.
echo '</ul>'; // Close the unordered list.
}
and now I have access to all the array elements I need:
just need to clean up the code (and use PDO instead for the communicating with the database)

Why can't my array variable be checked correctly for values?

So I have been working on a way to view a list of an employees and have employee options i.e buttons next to them to have it do an action in the database, but when I was making a promote to manager button It was supposed to disappear if that employee was already a manager but it only takes the first index of $managers, why won't it take all
<?php if(!in_array($row['employee_id'], $managers)) { ?>
<?php echo form_open('manager_controller/employee_promote', $class); ?>
<input type="button" name="promote" value="Promote" class="btn btn-success" onclick="form.submit()">
<input type="hidden" name="employee_id" value="<?php echo $row['employee_id'];?>">
<?php echo form_close(); ?>
<?php } ?>
Here's a print_r of $managers:
Array
(
[0] => Array
(
[employee_id] => 723
)
[1] => Array
(
[employee_id] => 2199
)
)
The code for how I get the $managers array.
//Sets which fields I am going to take
$this->db->select('employee_id, ssn, first_name, last_name, department, title, status');
//Sets which table it is going to get the fields
$query = $this->db->get('employees');
//Uses codeigniter's result_array function to convert the the object to an array
$results = $query->result_array();
//Returns the variable to my controller so I can access it in my view.
return $results;
You will need to loop through the array.
foreach($managers as $manager)
if($row['employee_id'] != $manager['employee_id']) {

CakePHP - Associate item status code to status txt

I usually save itens status within a code (let's save I have the table: students, to save studentes status, I use the field (students.status)).
But, Everytime I list Users I will not shown the status code (1 or 0 for example). I need show: Registered or Cancelled.
I can simply check it when I list, but, let's say I need do it a lot of times.
Is there anything than can help me doing it? would save a lot of work, every page I'll list the user, or even when I add/edit him or a drop-down menu that should come with those items.
I've checked the models associations, but the solution that I've found works if I have another table with user status saved for example (I honestly don't wanna create it).
Thanks.
This describes how to do what you want: http://www.dereuromark.de/2010/06/24/static-enums-or-semihardcoded-attributes/
If the status can be registered or cancelled then you can use enum data type in your table schema.
You can get the list of status from enum data type for populating drop down like this.
$status = $this->Model->getEnumValues('status');
Before this you need to add following code in your appModel.php
function getEnumValues($columnName=null)
{
if ($columnName==null) { return array(); } //no field specified
//Get the name of the table
$db =& ConnectionManager::getDataSource($this->useDbConfig);
$tableName = $db->fullTableName($this, false);
//Get the values for the specified column (database and version specific, needs testing)
$result = $this->query("SHOW COLUMNS FROM {$tableName} LIKE '{$columnName}'");
//figure out where in the result our Types are (this varies between mysql versions)
$types = null;
if ( isset( $result[0]['COLUMNS']['Type'] ) ) { $types = $result[0]['COLUMNS']['Type']; } //MySQL 5
elseif ( isset( $result[0][0]['Type'] ) ) { $types = $result[0][0]['Type']; } //MySQL 4
else { return array(); } //types return not accounted for
//Get the values
$values = explode("','", preg_replace("/(enum)\('(.+?)'\)/","\\2", $types) );
//explode doesn't do assoc arrays, but cake needs an assoc to assign values
$assoc_values = array();
foreach ( $values as $value ) {
//leave the call to humanize if you want it to look pretty
$assoc_values[$value] = Inflector::humanize($value);
}
return $assoc_values;
}
I hope this will work for you. Thanks
I ended up creating a Helper function for that (not sure if the best way, it's been working fine)
MyHelper.php
class MyHelper extends AppHelper {
public $helpers = array();
public $list = array(0 => 'Cancelled', 1 => 'Registered');
public function __construct(View $View, $settings = array()) {
parent::__construct($View, $settings);
}
public function beforeRender($viewFile) {
}
public function afterRender($viewFile) {
}
public function beforeLayout($viewLayout) {
}
public function afterLayout($viewLayout) {
}
public function translate($id){
return $this->list[$id];
}
}
In view.ctp, intestead of showing the item ID, I just call the translate function, returning the proper name.
To create drop-down menus, it's just call the array list in select options.
<?php
echo "User Status: " . $this->My->translate($this->User->status);
echo $this->Form->input('tipo', array('type' => 'select', 'options' => $this->My->list));
?>
I think I should have used enum too, and using the functions specified, I would have success too.
Thanks for the helps.
You might want to look at model associations. In your case, I would have a students table and a student_statuses table that contains an ID and a status name. Then, when finding students, you can also include their corresponding StudentStatus row.
This relationship would look as follows:
<?php
class Student extends AppModel {
public $belongsTo = array('StudentStatus');
}
<?php
class StudentStatus extends AppModel {
public $hasMany = array('Student');
}
Then when finding students…
<?php
class StudentsController extends AppController {
public function index() {
$this->set('students', $this->Student->find('all'));
}
}
You will get a result like this:
Array
(
[0] => Array
(
[Student] => Array
(
[id] => 1
[name] => Martin Bean
[student_status_id] => 1
[created] => 2013-09-29 21:12:42
[modified] => 2013-09-29 21:12:42
)
[StudentStatus] => Array
(
[0] => Array
(
[id] => 1
[name] => Approved
[created] => 2013-09-23 18:26:06
[modified] => 2013-10-01 18:53:16
)
)
)
)
So you can just print the students’ status in your view as follows:
<?php foreach ($students as $student): ?>
<p>
<?php echo h($student['Student']['name']); ?>
(<?php echo h($student['StudentStatus']['name']); ?>)
</p>
<?php endforeach; ?>
You say you don’t want to create a table for statuses, but the reason you’re having issues is because it’s how relational databases work and also the convention. You’ll save yourself a lot of headaches by doing so, and it’s also extensible if you decide you need to add additional statuses in the future. You may not think you do now, but believe me: one day you will.

Form dropdown function

I'm trying to work with the form dropdown function for the codeigniter form helper.
echo form_dropdown('userCharacters', $userRoster, '', '', 'id="userCharacter"');
If you notice the $userRoster is the array I pass from the controller to the view.
Here's how it shows up when I do a print_r on the array.
Array
(
[0] => stdClass Object
(
[id] => 1
[rosterName] => Kid Wonder
)
[1] => stdClass Object
(
[id] => 3
[rosterName] => Oriel
)
)
However I am getting these errors and not sure why
A PHP Error was encountered
Severity: 4096
Message: Object of class stdClass could not be converted to string
Filename: helpers/form_helper.php
Line Number: 352
A PHP Error was encountered
Severity: 4096
Message: Object of class stdClass could not be converted to string
Filename: helpers/form_helper.php
Line Number: 352
EDIT :
Array
(
[0] => Array
(
[id] => 1
[rosterName] => Kid Wonder
)
[1] => Array
(
[id] => 3
[rosterName] => Oriel
)
)
EDIT 2 :
What's supposed to happen is after the user logs in it has the default character id and the role id of the user that is held in the userData array. It runs the library function getRosterList. Inside that function it checks to see if the user has a role id of 4(admin) or 5(superadmin) and if they are then what I want it to do is get ALL the roster members which would include their default character and have it as the selected option. If they are not one of those two roles then I just want it to get the roster members that they control and have the preselected option as the default character id. And if they only have one character then it displays a h1 tag instead of the dropdown.
Controller:
$this->data['userData'] = $this->users->getUserByUserID($this->session->userdata('userID'));
$this->data['userRoster'] = $this->kowauth->getRosterList($this->data['userData']->usersRolesID);
Library (kowauth)
* Get roster list
*
* #param integer
* #return object/NULL
*/
function getRosterList($usersRolesID)
{
// Check args
if(!is_numeric($usersRolesID)) { throw new Exception('Non-numeric $usersRolesID provided to getRosterList()'); }
if (($usersRolesID == 4) || ($usersRolesID == 5))
{
return $this->ci->users->getAllRoster();
}
else
{
return $this->ci->users->getRosterByUserID($this->ci->session->userdata('userID'));
}
}
Model:
/**
* Get roster list
*
* #return object/NULL
*/
function getAllRoster()
{
$this->db->select('id');
$this->db->select('rosterName');
$this->db->select('rosterStatusID');
$this->db->from('rosterList');
$this->db->order_by('rosterName');
$query = $this->db->get();
if ($query->num_rows() > 0)
{
return $query->result();
}
return null;
}
/**
* Get list of roster by user ID
*
* #return object/NULL
*/
function getRosterByUserID($userID)
{
// Check args
if (!is_numeric($userID)) { throw new Exception('Non-numeric $userID provided to getRosterByUserID()'); }
$this->db->select('id');
$this->db->select('rosterName');
$this->db->from('rosterList');
$this->db->where('userID', $userID);
$this->db->order_by('rosterName');
$query = $this->db->get();
if ($query->num_rows() > 0)
{
return $query->result_array();
}
return null;
}
View:
<?php
echo '<pre>';
print_r($userRoster);
echo '</pre>';
if (count($userRoster) == 1)
{
echo '<h1>'.$userRoster->rosterName.'</h1>';
}
else
{
$options = array (
$userRoster['id'] => $userRoster->rosterName
);
echo form_dropdown('userCharacters', $options, '', 'id="userCharacter"');
}
?>
Anybody have any ideas on this?
You're currently passing an array of objects. I believe that your $userRoster array should be formatted like this:
Array
(
1 => 'Kid Wonder'
3 => 'Oriel'
)
Also, I believe that form_dropdown only takes four parameters and you're trying to pass it five. You might want to move that last argument into the fourth spot:
echo form_dropdown('userCharacters', $userRoster, '', 'id="userCharacter"');
Should produce:
<select name="userCharacters" id="userCharacter">
<option value="1">Kid Wonder</option>
<option value="3">Oriel</option>
</select>
Which I think is what you're going for!
http://codeigniter.com/user_guide/helpers/form_helper.html

Categories