Reusable function for getting mysql data - php

I want to write a function which is able to return the sum of the total_excl column at the MySQL database. I’ve written a function, but its not reusable.
The function for the first quarter of the year.
public static function getFirstQuarterTotalExcl(){
$first_day_of_1_quarter = date('Y-01-01');
$last_day_of_1_quarter = date('Y-03-31');
$query = "SELECT SUM(total_excl) FROM ".Zim_Properties::getTableName('Invoice')." WHERE invoice_date BETWEEN '$first_day_of_1_quarter' AND '$last_day_of_1_quarter'";
$total = Zend_Registry::get('db')->fetchAll($query);
return round($total[0]["SUM(total_excl)"]);
}
The second function for the second quarter of the year:
public static function getSecondQuarterTotalExcl(){
$first_day_of_2_quarter = date('Y-04-01');
$last_day_of_2_quarter = date('Y-06-30');
$query = "SELECT SUM(total_excl) FROM ".Zim_Properties::getTableName('Invoice')." WHERE invoice_date BETWEEN '$first_day_of_2_quarter' AND '$last_day_of_2_quarter'";
$total = Zend_Registry::get('db')->fetchAll($query);
return round($total[0]["SUM(total_excl)"]);
}
As you can see. This code isn’t reusable which means that for every quarter of the year I have to write a new function. I want to make one function for every quarter. What should I do to make it reusable?

I’ve written a function, but its not reusable.
No clear on what you mean here, but what about just setting the dates as part of the interface to the function like this:
public static function getQuarterTotalExcl($first_day_of_quarter,$last_day_of_quarter){
// $first_day_of_2_quarter = date('Y-04-01');
// $last_day_of_2_quarter = date('Y-06-30');
$query = "SELECT SUM(total_excl) FROM ".Zim_Properties::getTableName('Invoice')." WHERE invoice_date BETWEEN '$first_day_of_quarter' AND '$last_day_of_quarter'";
$total = Zend_Registry::get('db')->fetchAll($query);
return round($total[0]["SUM(total_excl)"]);
}
Then just call it like this:
$first_quarter_results = getQuarterTotalExcl(date('Y-01-01'), date('Y-03-31'));
$second_quarter_results = getQuarterTotalExcl(date('Y-04-01'), date('Y-06-30'));
$third_quarter_results = getQuarterTotalExcl(date('Y-07-01'), date('Y-09-30'));
$fourth_quarter_results = getQuarterTotalExcl(date('Y-10-01'), date('Y-12-31'));

Pass the two dates as parameters to your general function.
Something like:
function getQuarterTotalExcl($day1, $day2)
{
$query = "SELECT SUM(total_excl) FROM ".Zim_Properties::getTableName('Invoice')." WHERE invoice_date BETWEEN '$day' AND '$day2'";
$total = Zend_Registry::get('db')->fetchAll($query);
return round($total[0]["SUM(total_excl)"]);
}

Related

array_unique() function in PHP does not work for my array

I have create a function for chat. I want to get only one value from set of values. I used array_unique function in it.
Error:
function get_chat_list($sender){
global $conn;
$sqlCode = "SELECT DISTINCT sender FROM chat WHERE connector LIKE '%$sender%' ";
$sqlCode1 = "SELECT DISTINCT reciever FROM chat WHERE connector LIKE '$sender%'";
var_dump($sqlCode1);
$run = mysqli_query($conn,$sqlCode);
$run1 = mysqli_query($conn,$sqlCode1);
var_dump($run1);
$recievers = array();
while($reciever = mysqli_fetch_assoc($run)){
if($reciever['sender'] == $sender){
}else{
$recievers[] = array('reciever'=>$reciever['sender']);
}
}
while($reciever = mysqli_fetch_assoc($run1)){
if($reciever['reciever'] == $sender){
}else{
$recievers[] = array('reciever'=>$reciever['reciever']);
}
}
return array_unique($recievers);
}
Error image
You are trying to make string comparisons on arrays (non-scalar). I don't think array_unique works on an array of arrays, it has to be array of strings. If you want unique receivers, you're going to need to turn that value into a string.
I don't know what you might be using the array for, but one solution would be to serialize/stringify the array and then you can run your unique, then unwrap/desalinize the string later. I'm not sure why if there is only one value in that array, you are using a key for it. How about just storing the string and it should work for you
EX:
function get_chat_list($sender){
global $conn;
$sqlCode = "SELECT DISTINCT sender FROM chat WHERE connector LIKE '%$sender%' ";
$sqlCode1 = "SELECT DISTINCT reciever FROM chat WHERE connector LIKE '$sender%'";
var_dump($sqlCode1);
$run = mysqli_query($conn,$sqlCode);
$run1 = mysqli_query($conn,$sqlCode1);
var_dump($run1);
$recievers = array();
while($reciever = mysqli_fetch_assoc($run)){
if($reciever['sender'] != $sender){
$recievers[] = $reciever['sender'];
}
}
while($reciever = mysqli_fetch_assoc($run1)){
if($reciever['reciever'] != $sender){
$recievers[] = $reciever['reciever'];
}
}
return array_unique($recievers);
}

Code igniter database calculate column average

I need to calculate in a function the average score of a column named: "totalscore" from my database table "score"
I tried to do Active record select_avg() but I am not getting anything.
Any idea how I can do this?
function calculateaverage(){
$dataArr = array();
$data = $this->db->get('score');
$maxrows = $data->num_rows();
$data = $this->db->get('score');
for ($i = 1; $i<= $maxrows-1; $i++){
$this->db->select('totalscore');
foreach ($data->result() as $row) {
$dataArr[$i] = $row->totalscore;
}
}
return $dataArr;
}
You can try this code, very simple and straight forward. write it in your model. use in Controller like $this->yourmodel->calculateaverage;
basically we are telling codeigniter query builder to select the AVG of our totalscore..
function calculateaverage(){
$query = $this->db->select('AVG(totalscore) as average_score')->from('score')->get();
return $query->row()->average_score;
}

Array and for each loop issues

Code is below if I run one value in the array the results are correct if I run more than one value the results are of the price is incorrect its like it has messed around with the values somewhere ?? help appreciated
$dido=array('42204131','22204131');
foreach($dido as $did):
$query = "select * from dispatch,link where lid=dlid and did=$did";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$vanc1=$row['vanc1'];
$vanc2=$row['vanc2'];
$vanc3=$row['vanc3'];
$vanc4=$row['vanc4'];
$vanc5=$row['vanc5'];
$anc1=$row['anc1'];
$anc2=$row['anc2'];
$anc3=$row['anc3'];
$anc4=$row['anc4'];
$anc5=$row['anc5'];
// price anc1
$querypanc1 = "select pprice from products where pid=$anc1";
$resultpanc1 = mysql_query($querypanc1);
while($row = mysql_fetch_array($resultpanc1))
{
$priceanc1=$row[pprice];
$tpriceanc1=$vanc1*$priceanc1;
}
// price anc2
$querypanc2 = "select pprice from products where pid=$anc2";
$resultpanc2 = mysql_query($querypanc2);
while($row = mysql_fetch_array($resultpanc2))
{
$priceanc2=$row[pprice];
$tpriceanc2=$vanc2*$priceanc2;
}
// price anc3
$querypanc3 = "select pprice from products where pid=$anc3";
$resultpanc3 = mysql_query($querypanc3);
while($row = mysql_fetch_array($resultpanc3))
{
$priceanc3=$row[pprice];
$tpriceanc3=$vanc3*$priceanc3;
}
// price anc4
$querypanc4 = "select pprice from products where pid=$anc4";
$resultpanc4 = mysql_query($querypanc4);
while($row = mysql_fetch_array($resultpanc4))
{
$priceanc4=$row[pprice];
$tpriceanc4=$vanc4*$priceanc4;
}
// price anc5
$querypanc5 = "select pprice from products where pid=$anc5";
$resultpanc5 = mysql_query($querypanc5);
while($row = mysql_fetch_array($resultpanc5))
{
$priceanc5=$row[pprice];
$tpriceanc5=$vanc5*$priceanc5;
}
$gtprice=$tpriceanc1+$tpriceanc2+$tpriceanc3+$tpriceanc4+$tpriceanc5;
$qrygt="UPDATE dispatch SET gtprice=$gtprice WHERE did=$did";
$resultgt=#mysql_query($qrygt);
}
endforeach;
1) The only possible issue I could spot in your code, is that when some of your select pprice from products where pid ... queries do not return any data, you retain value of $tpriceancX from previous iteration.
2) Also (out of topic) you can replace your 5 blocks of repeated code with for loop.
$gtprice = 0;
for ($i = 1; $i <= 5; $i++)
{
$querypanc = "select pprice from products where pid=".$row["anc$i"];
$resultpanc = mysql_query($querypanc);
while($pancrow = mysql_fetch_array($resultpanc))
{
$priceanc=$pancrow[pprice];
$tpriceanc=$row["vanc$i"]*$priceanc;
$gtprice += $tpriceanc;
}
}
Your first and biggest problem is the copy-pasta nature of your code. Let's try and break down what you're doing:
Setting up a list of ids
Running a query on those ids
Putting the results into an array
Running a separate query on each of those results
You are also using some very janky syntax. (ie foreach($foo as $bar):).
Break these things down into methods. What is a method? It takes an input and transforms it into an output.
//returns an array of price information
public function getPrices($idArray) { //note the good method and parameter names!
//do stuff
}
Now that we know what we are doing, we can start to fill in the implementation details:
public function getPrices($idArray) {
foreach($idArray as $id) {
//somehow get the gross-scale information
//then put it in a data object
//then call a function to get specific information
}
}
What should that sub-method do? Lets look at your current code snippet:
// price anc1
$querypanc1 = "select pprice from products where pid=$anc1";//sets up sql query
$resultpanc1 = mysql_query($querypanc1); //runs the query
while($row = mysql_fetch_array($resultpanc1)) { //for each result
$priceanc1=$row[pprice]; //gets the price
$tpriceanc1=$vanc1*$priceanc1; //calculates some other price
}
Those last two lines really suggest an object but maybe that's too heavyweight for your purpose. The first two lines are boiler plate you repeat endlessly. Lets write a function!
public function getPrices($name, $pid, $multiplier) {
$sqlQuery = "SELECT pprice FROM products WHERE pid=$pid";
$result = mysql_query($sqlQuery);
$prices = array();
while ($row = mysql_fetch_array($result) {
$key = "price".$name;//$key will be something like 'priceanc1'
$prices[$key] = $row[pprice];
$tkey = "tprice".$name;
$prices[$tkey] = $prices[$key] * $multiplier;
}
}
Now, this function is a bit unclean because it tries to do two things at once (queries the database and then massages the data into a usable array) but I wanted it to resemble what you were doing. With this function written we can go back to our higher level function an call it:
public function getPrices($idArray) {
foreach($idArray as $id) {
$sqlQuery = "SELECT * from dispatch, link WHERE lid=dlid and did=$id";
$prices = array();
while ($row = mysql_fetch_array($result) {
for ($idx = 1; $idx <= 5; $idx++) {
$name = "anc".$idx;
$pid = $row[$name];
$multiplier = $row["vanc".$idx];
$priceArray = getPrices($name, $pid, $multiplier);
$prices = array_merge($prices, $priceArray);
}
}
}
//put a var_dump here to check to see if you're getting good results!
return $prices;//Should be the aggregated prices you've gotten from the db
}
Now, that is what you're attempting to do, but I admit I don't understand how your database is set up or what your variables actually mean. Pressing on! We also note that unnecessary massaging of data falls away.
You can call this like so:
$ids = array();
$ids[] = 42204131;
$ids[] = 22204131;
$prices = getPrices($ids);
var_dump($prices);//shows the result of your work
Now that you have the prices, you can pass them to another function to run the update:
updatePrices($prices);
I'll let you write that part on your own. But remember; break down what you're doing and have repeated elements be handled by the same function. The real lesson to learn here is that programming is really communicating: your code doesn't communicate anything because there is so much repeated noise. Use good variable names. Tighten what you're doing down to functions with single tasks. This way anyone reading your code (including you!) will know what you're trying to do and where you've gone wrong.

SocialEngine 4 Calculate days left in membership

What I am trying to do is show a small widget on the home page to let a user know when their membership expires. Here is my current code
$subExpire = Engine_Api::_()->getDbtable('subscriptions', 'payment');
$db2 = $streamTable->getAdapter();
$stmt2 = $db2->query("select * from engine4_payment_subscriptions where `user_id`='$user_id'");
$arr2 = $stmt2->fetch();
if ($arr2['expiration_date']=="NULL")
{
$exp = "NEVER";
}
echo $exp;
I think the major issue has to do with Engine_Api::_()->getDbtable('subscriptions', 'payment');
Ultimately once it comes back with a date I would like to calculate how many days left in the membership from the current date.
Any suggestions?
PS, $user_id is defined and does return a numeric value
One more thing, the actual table name is engine4_payment_subscriptions
That´s a strange way of making the query in social engine, try this:
$table = Engine_Api::_()->getDbtable('subscriptions', 'payment');
$select = $table->select()->where('user_id = ?', $user_id);
$arr2 = $table->fetchAll($select);
if ($arr2['expiration_date']=="NULL")
{
$exp = "NEVER";
}
echo $exp;

CodeIgniter problem with limit

I have a LoteModel:
public function selecionar($where = NULL, $limit = NULL, $order_by = NULL) {
if(!is_null($where)) {
$this->db->where($where);
}
if(!is_null($limit)) {
$this->db->limit($limit);
}
if(!is_null($order_by)) {
$this->db->order_by($order_by);
}
return $this->db->get(_LOTE_);//_LOTE_ is a constant for my table name
}
and I call it like this:
$config['per_page'] = '5';
$limite = $config['per_page'].','.$this->uri->segment(3); //the segment is ok, I receive it
$lotes = $this->LoteModel->selecionar(array('quadra_id'=>$quadra_id, 'lote_status'=>1), $limite, 'lote_endereco');
I have checked the SQL result for that query:
SELECT * FROM (`realestate_lote`) WHERE `quadra_id` = '1' AND `lote_status` = 1 ORDER BY `lote_endereco`
The thing is, it’s not generating my LIMIT, it will only work if I add it to the LoteModel method.
I’m working with pagination.
Thanks in advance for any help =)
You can't pass a string like "5,1" to CI's ActiveRecord limit function.
The function requires two parameters.
Split the limit string by "," and pass the two values like the example below.
$limit = explode(',', $limit);
$this->db->limit($limit[0], $limit[1]);
Hope this helps...

Categories