I have the following model functions with PHP.
I know I am repeating myself.
Is there anyway I can simplify this code?
function getTopMenus(){
$data[0] = 'root';
$this->db->where('parentid',0);
$Q = $this->db->get('menus');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[$row['id']] = $row['name'];
}
}
$Q->free_result();
return $data;
}
function getheadMenus(){
$this->db->where('parentid',0);
$Q = $this->db->get('menus');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[] = $row;
}
}
$Q->free_result();
return $data;
}
function getrootMenus(){
$this->db->where('parentid',0);
$Q = $this->db->get('menus');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[$row['id']] = $row['name'];
}
}
$Q->free_result();
return $data;
}
I can see one simplification you might try, using pass-by-reference to factor things out into a function:
function prepareMenu(&$data) {
$this->db->where('parentid',0);
$Q = $this->db->get('menus');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$data[$row['id']] = $row['name'];
}
}
$Q->free_result();
}
function getTopMenus() {
$data[0] = 'root';
prepareMenus($data);
return $data;
}
function getRootMenus() {
prepareMenus($data);
return $data;
}
There's also the possibility of using pass-by-reference and variable functions to factor out the part in the middle. May reduce duplication, but may or may not be considered 'simplifying'.
EDIT Here's what I mean. This code is untested.
function getMenus(&$data, $appendFunc) {
$this->db->where('parentid',0);
$Q = $this->db->get('menus');
if ($Q->num_rows() > 0){
foreach ($Q->result_array() as $row){
$appendFunc(&$data, $row);
}
}
$Q->free_result();
}
function appendTopMenu(&$data, $row) {
$data[$row['id']] = $row['name'];
}
function appendHeadMenu(&$data, $row) {
$data[] = $row;
}
function getTopMenus() {
$data[0] = 'root';
getMenus($data, "appendTopMenu");
return $data;
}
function getheadMenus() {
getMenus($data, "appendHeadMenu");
return $data;
}
function getrootMenus() {
getMenus($data, "appendTopMenu");
return $data;
}
Why not pass parameters into your function and place them in the 'where' and 'get' methods?
I don't know what your db and query classes look like, but i'd start improving these in the first place. Add "array fetch" and "hash fetch" functions to the query class:
class Query ...
function as_array() {
$data = array();
if($this->num_rows() > 0)
foreach ($this->result_array() as $row)
$data[] = $row;
$this->free_result();
return $data;
}
function as_hash($key = 'id') {
$data = array();
if($this->num_rows() > 0)
foreach ($this->result_array() as $row)
$data[$row[$key]] = $row;
$this->free_result();
return $data;
}
Make 'db->where()' return itself
class DB
function where(...) {
stuff
return $this;
Once you have this, your client functions become trivial:
function getTopMenus() {
$data = $this->db->where('parentid',0)->get('menus')->as_hash();
$data[0] = 'root';
return $data;
}
function getheadMenus() {
return $this->db->where('parentid',0)->get('menus')->as_array();
}
function getrootMenus() {
return $this->db->where('parentid',0)->get('menus')->as_hash();
}
Related
This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 5 years ago.
I have an array like below,
[{
"name":"Daniel",
"connection_status":"1"
},
{
"name":"Danny",
"connection_status":"3"
},
{
"name":"Moris",
"connection_status":"2"
},
{
"name":"Manny",
"connection_status":"1"
}]
I want to sort my array by status like 1,2,3 in this order.
This is my code,
public function getProfileDataForMySociety($user_id)
{
$this->db->select('*');
$this->db->from('profile');
$this->db->where('profile_id!=', $user_id);
$query = $this->db->get();
$list = $query->result();
$friends = $this->checkFriends($list, $user_id);
return $friends;
}
public function checkFriends($list, $user_id)
{
$array = [];
foreach ($list as $k => $v) {
// print_r(json_encode($list));
$friends = $this->checkStatus($v->profile_id);
//print_r($friends);
$relationship = '';
$relation_id = '';
foreach ($friends as $kk => $vv) {
if ($user_id == $vv->sent_id) {
if ($vv->status == 1) {
$relationship = 1;
}
if ($vv->status == 2) {
$relationship = 2;
}
} else if ($user_id == $vv->recieved_id) {
// pending
if ($vv->status == 1) {
$relationship = 3;
$relation_id = $vv->sent_id;
}
if ($vv->status == 2) {
$relationship = 4;
}
}
}
$list[$k]->connection_status = $relationship;
$list[$k]->relation_id = $relation_id;
}
return $list;
}
public function checkStatus($id)
{
$this->db->select('*');
$this->db->from('requests');
$this->db->where('sent_id', $id);
$this->db->or_where('recieved_id', $id);
$query = $this->db->get();
$list = $query->result();
return $list;
}
connection status is not a db field.
Where $list is my o/p array.Can anyone help me.Thanks in advance.
I want to sort my array based on my connection_status.
if i understand you correctly this may help you
public function getProfileDataForMySociety($user_id)
{
$this->db->select('*');
$this->db->from('profile');
$this->db->where('profile_id!=', $user_id);
$this->db->order_by('status', 'asc');
$query = $this->db->get();
$list = $query->result();
return $list;
}
You can apply order by in query
public function getProfileDataForMySociety($user_id)
{
$this->db->select('*');
$this->db->from('profile');
$this->db->where('profile_id!=', $user_id);
$this->db->order_by('status'); // USE ORDER BY
$query = $this->db->get();
$list = $query->result();
return $list;
}
public function getProfileDataForMySociety($user_id)
{
$this->db->select('*');
$this->db->from('profile');
$this->db->where('profile_id!=', $user_id);
$query = $this->db->order('status asc')->get();
$list = $query->result();
return $list;
}
why this code not work?
my model
public function get_question_by_testid($id) {
$this->db->select('question, description, name');
$this->db->from('question');
$this->db->join('test', 'test.id = question.testid');
$this->db->where('testid', $id);
$query = $this->db->get();
$result = $query->result_array();
$count = count($result);
if (empty($count) || $count > 1) {
$question = null;
return $question;
} else {
return $result;
}
}
why this code not work?
//controller function test($id = NULL) {
$data['tests'] = $this->student_model->get_test_by_id($id);
$data['questions'] = $this->student_model->get_question_by_testid($id);
$this->load->view('studentExam',$data);
}
why does this code not work?
//view
foreach ($tests as $test)
{
echo $test['name'];
echo '</br>';
echo $test['description'];
}
foreach ($questions as $question) {
echo $question['test'];
echo $question['question'];
echo '</br>';
}
You have to change this line:
$this->db->where('testid', $id);
To this:
$this->db->where('question.testid', $id);
I wrote this function for caching queries:
function get_cached($query, $type = 1) {
$key = md5(strtolower($query));
$cached = $memcache->get($key);
if($cached) {
$res = unserialize($cached);
} else {
$r = mysql_query($query);
if($mode == 1) {
$res = mysql_fetch_object($r);
} else {
$res = mysql_fetch_array($r);
}
$memcache->store($key, serialize($res));
}
return $res;
}
And it kinda works, i can cache simple queries. But i have problem with queries that operate within loops.
I really can't understand how to get around this, and "port" this to use my get_cached() function first.
$ref = mysql_query("query");
while($res = mysql_fetch_object($ref)) {
//do something with results
}
How i can do it through cache?
You cannot store the mysql result object but you can fetch all rows into an array and cache the array. like
function get_cached($query, $type = 1) {
$key = md5(strtolower($query) . $type);
$cached = $memcache->get($key);
if($cached) {
return unserialize($cached);
} else {
$r = mysql_query($query);
$data = array();
if($mode == 1) {
foreach($row = mysql_fetch_object($r)) {
$data[] = $row;
}
} else {
foreach($row = mysql_fetch_array($r)) {
$data[] = $row;
}
}
$memcache->store($key, serialize($data));
}
return $data;
}
don't forget to store the type of your functions as cache key too, otherwise you fetch a results set with type==1 and in return you get the elements as array
I'm using this database MySQLi wrapper:
Class dbWrapper {
protected $_mysqli;
protected $_debug;
public function __construct($host, $username, $password, $database, $debug) {
$this->_mysqli = new mysqli($host, $username, $password, $database);
$this->_mysqli->set_charset("utf8");
$this->_debug = (bool) $debug;
if (mysqli_connect_errno()) {
if ($this->_debug) {
echo mysqli_connect_error();
debug_print_backtrace();
}
return false;
}
return true;
}
public function q($query) {
if ($query = $this->_mysqli->prepare($query)) {
if (func_num_args() > 1) {
$x = func_get_args();
$args = array_merge(array(func_get_arg(1)),
array_slice($x, 2));
$args_ref = array();
foreach($args as $k => &$arg) {
$args_ref[$k] = &$arg;
}
call_user_func_array(array($query, 'bind_param'), $args_ref);
}
$query->execute();
if ($query->errno) {
if ($this->_debug) {
echo mysqli_error($this->_mysqli);
debug_print_backtrace();
}
return false;
}
if ($query->affected_rows > -1) {
return $query->affected_rows;
}
$params = array();
$meta = $query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($query, 'bind_result'), $params);
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
} else {
if ($this->_debug) {
echo $this->_mysqli->error;
debug_print_backtrace();
}
return false;
}
}
public function handle() {
return $this->_mysqli;
}
}
But when I make a query, for example SELECT This FROM Database, and I want to display the result, I have to echo $result[0]['This']. Why that? Why not $result['This']? I changed this:
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
to this:
$result = array();
while ($query->fetch()) {
foreach ($row as $key => $val) {
$result[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
But why do all the wrappers I see, return a multidimensional array?
Hope you understand me. Thank you!
The reason they return multidimensional arrays is because you can have more than one result.
So:
$data[0]['name'] is the first returned records name.
$data[1]['name'] is the second returned records name.
You can create a fetchRow() function which will always just return the first record when you only expect one row
return $data[0]
OR
a fetchOne()
return $data[0]['name']
When you only expect one field
Usually, when you're gathering results from a DB query, you have multiple rows.
--------------
- 1 --- This -
- 2 --- That -
--------------
So you get a multi-dimensional array in order to handle all the rows in one object.
...Is that not the case here?
EDIT:
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
in the above code, you are assigning each individual row to an index in the $results array. In order to access them, you need to provide $results[ROW_NUMBER][KEY_NAME];
Does that make sense?
I'm going to take a shot and say maybe try $query->fetch_row() instead of $query->fetch() (just a guess)
I have a simple function:
function test(){
//some code
$X_has_val = $Y_has_val= array();
foreach ($A as $id => $row){
if(is_take($id)){
$X_has_val[$id] = $row;
}
}
foreach ($B as $id => $row){
if(is_take($id)){
$Y_has_val[$id] = $row;
}
}
//some code
}
I did this for get the equivalence
function test(){
//some code
$X_has_val = $Y_has_val= array();
foreach(array($A, $B) as $key=>$value){
foreach ($value as $id => $row){
if(is_take($id)){
$X_has_val[$id] = $row;
continue;
$Y_has_val[$id] = $row;
}
}
}
//some code
}
Looks like all you need is array_filter()
$X_has_cc = array_filter($A, 'isTake');
$Y_has_cc = array_filter($B, 'isTake');
like e.g. in
<?php
test();
function test() {
$A = array(1,2,3,4,5,6,7,8,9,10);
$B = array(99,100,101,102,103,104);
$X_has_cc = array_filter($A, 'isTake');
$Y_has_cc = array_filter($B, 'isTake');
var_dump($X_has_cc, $Y_has_cc);
}
// select "even elements"
function isTake($x) {
return 0==$x%2;
}
(and sorry, no, your approach doesn't make much sense ;-))