how to test Laravel controller which reads information from .json file - php

I'm new in Laravel and PHPUnit. I'm trying to test controller, which read .json file, execute some calculation and returning result like this [3,3,2,0.5].
How can i send .json file or some value to controller and check feedback results?
Thank you in advance
controller:
namespace App\Http\Controllers;
class payController extends Controller
{
public function index()
{
$ratio = [];
$ratio1= [];
$string = file_get_contents("input.json");
if(!isset($string)){
echo 'File is empty.';
} else {
$json_a = json_decode($string, true);
$required_income = $json_a['required_income'];
foreach ($json_a['sms_list'] as $json) {
$ratio_value = $json['income'] * 100 / $json['price'];
array_push($ratio, [$ratio_value, $json['price'], $json['income']]);
}
foreach ($json_a['sms_list'] as $json) {
array_push($ratio1, [$json['price'], $json['income']]);
}
$count = count($ratio);
rsort($ratio, 0);
$smsPrice = [];
for ($i = 0; $i < $count; $i++) {
$price = $ratio[$i][1];
$income = $ratio[$i][2];
$divisionRequiredIncome = floor($required_income / $price);
if ($divisionRequiredIncome > 0) {
for ($j = 0; $j < $divisionRequiredIncome; $j++) {
array_push($smsPrice, $price);
}
$required_income -= ($income * $divisionRequiredIncome);
}
}
sort($ratio1, 1);
for ($i = 0; $i < $count; $i++) {
if ($required_income - $ratio1[$i][1] <= 0) {
array_push($smsPrice, $ratio1[$i][0]);
break;
}
}
}
echo '<pre>';
var_dump($smsPrice);
}
}
payControllerTest:
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Http\Controllers\payController;
class payControllerTest extends TestCase
{
/**
* A basic unit test example.
*
* #return void
*/
public function test_first()
{
$res = payController::index();
}
}
input.json file:
{
"sms_list": [
{"price": 0.5, "income": 0.41},
{"price": 1, "income": 0.96},
{"price": 2, "income": 1.91},
{"price": 3, "income": 2.9}
],
"required_income": 8
}

Related

I want to refactor two nested foreaches and break it into separate functions

I have a big foreach where I do many calculations and it looks too messy and bad, that's why I want to break it into more functions but I don't know how since I don't know what arguments should I pass to my sub-functions
Here is my code
$dataset = 'supplier_invoices';
$SupplierInvoice = new Dbm_Supplier($dataset);
$totalValoare = 0;
$costAdaos = 0;
$totalTva_neex = 0;
$totalVal_cu_tva = 0;
$totalValoareCantitateNegativaProduseFacturate = 0;
$costAdaosCantitateNegativaProduseFacturate = 0;
$totalTva_neexCantitateNegativaProduseFacturate = 0;
$totalVal_cu_tvaCantitateNegativaProduseFacturate = 0;
$totalValoarePozitivaProduseFacturate = 0;
$costAdaosPozitivaProduseFacturate = 0;
$totalTva_neexPozitivaProduseFacturate = 0;
$totalVal_cu_tvaPozitivaProduseFacturate = 0;
$totalValoareProduseFurnizor = 0;
$costAdaosProduseFurnizor = 0;
$totalTva_neexProduseFurnizor = 0;
$totalVal_cu_tvaProduseFurnizor = 0;
$totalValoareProduseFurnizorReturnate = 0;
$costAdaosProduseFurnizorReturnate = 0;
$totalTva_neexProduseFurnizorReturnate = 0;
$totalVal_cu_tvaProduseFurnizorReturnate = 0;
foreach ($invoices as $invoice)
{
$data = $SupplierInvoice->findFirst(array('supplier_invoice_id'=>$invoice['supplier_invoice_id']));
$data = $data['results'];
$invoiceCalculus = new InvoiceSupplierCalculus($data['supplier_invoice_date'], $data['currency_rate']);
$products = $SupplierInvoice->getProductsForInvoice($invoice['supplier_invoice_id']);
foreach ($products as $product)
{
$calculus = $invoiceCalculus->getCalculus($product);
$valoare = $calculus['default_currency_value'];
$adaos_com = $calculus['adaos_com'];
$tva_neex = $calculus['tva_neex'];
$val_cu_tva = $calculus['val_cu_tva'];
$totalValoare += $valoare;
$costAdaos += $adaos_com;
$totalTva_neex += $tva_neex;
$totalVal_cu_tva += $val_cu_tva;
$totalVal_cu_tva = number_format($totalVal_cu_tva,2,'.','');
if($product['invoice_quantity'] < 0)
{
$totalValoareCantitateNegativaProduseFacturate += -1 * abs($valoare);
$costAdaosCantitateNegativaProduseFacturate += -1 * abs($adaos_com);
$totalTva_neexCantitateNegativaProduseFacturate += -1 * abs($tva_neex);
$totalVal_cu_tvaCantitateNegativaProduseFacturate += -1 * abs($val_cu_tva);
$totalVal_cu_tvaCantitateNegativaProduseFacturate = number_format($totalVal_cu_tvaCantitateNegativaProduseFacturate,2,'.','');
}
else
{
$totalValoarePozitivaProduseFacturate += abs($valoare);
$costAdaosPozitivaProduseFacturate += abs($adaos_com);
$totalTva_neexPozitivaProduseFacturate += abs($tva_neex);
$totalVal_cu_tvaPozitivaProduseFacturate += abs($val_cu_tva);
$totalVal_cu_tvaPozitivaProduseFacturate = number_format($totalVal_cu_tvaPozitivaProduseFacturate,2,'.','');
}
if($product['product_quantity'] < 0)
{
$totalValoareProduseFurnizorReturnate += $valoare;
$costAdaosProduseFurnizorReturnate += $adaos_com;
$totalTva_neexProduseFurnizorReturnate += $tva_neex;
$totalVal_cu_tvaProduseFurnizorReturnate += $val_cu_tva;
$totalVal_cu_tvaProduseFurnizorReturnate = number_format($totalVal_cu_tvaProduseFurnizorReturnate,2,'.','');
}
else
{
$totalValoareProduseFurnizor += $valoare;
$costAdaosProduseFurnizor += $adaos_com;
$totalTva_neexProduseFurnizor += $tva_neex;
$totalVal_cu_tvaProduseFurnizor += $val_cu_tva;
$totalVal_cu_tvaProduseFurnizor = number_format($totalVal_cu_tvaProduseFurnizor,2,'.','');
}
}
}
This code calculates prices of products listed on invoices. If a product has a minus before its quantity then it means that the product was returned and its price should be subtracted from the final total.
I would encapsulate all of the calculations and accumulated variables in a class, and in the loop just pass the necessary values into a function on the class that handles the logic.
<?php
class InvoiceTotalsAccumulator
{
private $totalValoare = 0;
private $costAdaos = 0;
private $totalTvaNeex = 0;
private $totalValCuTva = 0;
private $totalValoareCantitateNegativaProduseFacturate = 0;
private $costAdaosCantitateNegativaProduseFacturate = 0;
private $totalTvaNeexCantitateNegativaProduseFacturate = 0;
private $totalValCuTvaCantitateNegativaProduseFacturate = 0;
private $totalValoarePozitivaProduseFacturate = 0;
private $costAdaosPozitivaProduseFacturate = 0;
private $totalTvaNeexPozitivaProduseFacturate = 0;
private $totalValCuTvaPozitivaProduseFacturate = 0;
private $totalValoareProduseFurnizor = 0;
private $costAdaosProduseFurnizor = 0;
private $totalTvaNeexProduseFurnizor = 0;
private $totalValCuTvaProduseFurnizor = 0;
private $totalValoareProduseFurnizorReturnate = 0;
private $costAdaosProduseFurnizorReturnate = 0;
private $totalTvaNeexProduseFurnizorReturnate = 0;
private $totalValCuTvaProduseFurnizorReturnate = 0;
public function addProductCalculus($invoiceQuantity, $productQuantity, $valoare, $adaosCom, $tvaNeex, $valCuTva)
{
$this->totalValoare += $valoare;
$this->costAdaos += $adaosCom;
$this->totalTvaNeex += $tvaNeex;
$this->totalValCuTva += $valCuTva;
if ($invoiceQuantity < 0)
{
$this->totalValoareCantitateNegativaProduseFacturate += -1 * abs($valoare);
$this->costAdaosCantitateNegativaProduseFacturate += -1 * abs($adaosCom;
$this->totalTvaNeexCantitateNegativaProduseFacturate += -1 * abs($tvaNeex);
$this->totalValCuTvaCantitateNegativaProduseFacturate += -1 * abs($valCuTva);
}
else
{
$this->totalValoarePozitivaProduseFacturate += abs($valoare);
$this->costAdaosPozitivaProduseFacturate += abs($adaosCom;
$this->totalTva_neexPozitivaProduseFacturate += abs($tvaNeex);
$this->totalValCuTvaPozitivaProduseFacturate += abs($valCuTva);
}
if ($productQuantity < 0)
{
$this->totalValoareProduseFurnizorReturnate += $valoare;
$this->costAdaosProduseFurnizorReturnate += $adaosCom;
$this->totalTva_neexProduseFurnizorReturnate += $tvaNeex;
$this->totalValCuTvaProduseFurnizorReturnate += $valCuTva;
}
else
{
$this->totalValoareProduseFurnizor += $valoare;
$this->costAdaosProduseFurnizor += $adaosCom;
$this->totalTva_neexProduseFurnizor += $tvaNeex;
$this->totalValCuTvaProduseFurnizor += $valCuTva;
}
}
private function _formatNumberForOutput($number)
{
return number_format($number, 2, '.', '');
}
public function getTotalValoare()
{
return $this->totalValoare;
}
public function setTotalValoare(int $totalValoare)
{
$this->totalValoare = $totalValoare;
}
public function getCostAdaos()
{
return $this->costAdaos;
}
public function setCostAdaos(int $costAdaos)
{
$this->costAdaos = $costAdaos;
}
public function getTotalTvaNeex()
{
return $this->totalTvaNeex;
}
public function setTotalTvaNeex(int $totalTvaNeex)
{
$this->totalTvaNeex = $totalTvaNeex;
}
public function getTotalValCuTva()
{
return $this->_formatNumberForOutput($this->totalValCuTva);
}
public function setTotalValCuTva(int $totalValCuTva)
{
$this->totalValCuTva = $totalValCuTva;
}
public function getTotalValoareCantitateNegativaProduseFacturate()
{
return $this->totalValoareCantitateNegativaProduseFacturate;
}
public function setTotalValoareCantitateNegativaProduseFacturate(int $totalValoareCantitateNegativaProduseFacturate)
{
$this->totalValoareCantitateNegativaProduseFacturate = $totalValoareCantitateNegativaProduseFacturate;
}
public function getCostAdaosCantitateNegativaProduseFacturate()
{
return $this->costAdaosCantitateNegativaProduseFacturate;
}
public function setCostAdaosCantitateNegativaProduseFacturate(int $costAdaosCantitateNegativaProduseFacturate)
{
$this->costAdaosCantitateNegativaProduseFacturate = $costAdaosCantitateNegativaProduseFacturate;
}
public function getTotalTvaNeexCantitateNegativaProduseFacturate()
{
return $this->totalTvaNeexCantitateNegativaProduseFacturate;
}
public function setTotalTvaNeexCantitateNegativaProduseFacturate(int $totalTvaNeexCantitateNegativaProduseFacturate)
{
$this->totalTvaNeexCantitateNegativaProduseFacturate = $totalTvaNeexCantitateNegativaProduseFacturate;
}
public function getTotalValCuTvaCantitateNegativaProduseFacturate()
{
return $this->_formatNumberForOutput($this->totalValCuTvaCantitateNegativaProduseFacturate);
}
public function setTotalValCuTvaCantitateNegativaProduseFacturate(int $totalValCuTvaCantitateNegativaProduseFacturate)
{
$this->totalValCuTvaCantitateNegativaProduseFacturate = $totalValCuTvaCantitateNegativaProduseFacturate;
}
public function getTotalValoarePozitivaProduseFacturate()
{
return $this->totalValoarePozitivaProduseFacturate;
}
public function setTotalValoarePozitivaProduseFacturate(int $totalValoarePozitivaProduseFacturate)
{
$this->totalValoarePozitivaProduseFacturate = $totalValoarePozitivaProduseFacturate;
}
public function getCostAdaosPozitivaProduseFacturate()
{
return $this->costAdaosPozitivaProduseFacturate;
}
public function setCostAdaosPozitivaProduseFacturate(int $costAdaosPozitivaProduseFacturate)
{
$this->costAdaosPozitivaProduseFacturate = $costAdaosPozitivaProduseFacturate;
}
public function getTotalTvaNeexPozitivaProduseFacturate()
{
return $this->totalTvaNeexPozitivaProduseFacturate;
}
public function setTotalTvaNeexPozitivaProduseFacturate(int $totalTvaNeexPozitivaProduseFacturate)
{
$this->totalTvaNeexPozitivaProduseFacturate = $totalTvaNeexPozitivaProduseFacturate;
}
public function getTotalValCuTvaPozitivaProduseFacturate()
{
return $this->_formatNumberForOutput($this->totalValCuTvaPozitivaProduseFacturate);
}
public function setTotalValCuTvaPozitivaProduseFacturate(int $totalValCuTvaPozitivaProduseFacturate)
{
$this->totalValCuTvaPozitivaProduseFacturate = $totalValCuTvaPozitivaProduseFacturate;
}
public function getTotalValoareProduseFurnizor()
{
return $this->totalValoareProduseFurnizor;
}
public function setTotalValoareProduseFurnizor(int $totalValoareProduseFurnizor)
{
$this->totalValoareProduseFurnizor = $totalValoareProduseFurnizor;
}
public function getCostAdaosProduseFurnizor()
{
return $this->costAdaosProduseFurnizor;
}
public function setCostAdaosProduseFurnizor(int $costAdaosProduseFurnizor)
{
$this->costAdaosProduseFurnizor = $costAdaosProduseFurnizor;
}
public function getTotalTvaNeexProduseFurnizor()
{
return $this->totalTvaNeexProduseFurnizor;
}
public function setTotalTvaNeexProduseFurnizor(int $totalTvaNeexProduseFurnizor)
{
$this->totalTvaNeexProduseFurnizor = $totalTvaNeexProduseFurnizor;
}
public function getTotalValCuTvaProduseFurnizor()
{
return $this->_formatNumberForOutput($this->totalValCuTvaProduseFurnizor);
}
public function setTotalValCuTvaProduseFurnizor(int $totalValCuTvaProduseFurnizor)
{
$this->totalValCuTvaProduseFurnizor = $totalValCuTvaProduseFurnizor;
}
public function getTotalValoareProduseFurnizorReturnate()
{
return $this->totalValoareProduseFurnizorReturnate;
}
public function setTotalValoareProduseFurnizorReturnate(int $totalValoareProduseFurnizorReturnate)
{
$this->totalValoareProduseFurnizorReturnate = $totalValoareProduseFurnizorReturnate;
}
public function getCostAdaosProduseFurnizorReturnate()
{
return $this->costAdaosProduseFurnizorReturnate;
}
public function setCostAdaosProduseFurnizorReturnate(int $costAdaosProduseFurnizorReturnate)
{
$this->costAdaosProduseFurnizorReturnate = $costAdaosProduseFurnizorReturnate;
}
public function getTotalTvaNeexProduseFurnizorReturnate()
{
return $this->totalTvaNeexProduseFurnizorReturnate;
}
public function setTotalTvaNeexProduseFurnizorReturnate(int $totalTvaNeexProduseFurnizorReturnate)
{
$this->totalTvaNeexProduseFurnizorReturnate = $totalTvaNeexProduseFurnizorReturnate;
}
public function getTotalValCuTvaProduseFurnizorReturnate()
{
return $this->_formatNumberForOutput($this->totalValCuTvaProduseFurnizorReturnate);
}
public function setTotalValCuTvaProduseFurnizorReturnate(int $totalValCuTvaProduseFurnizorReturnate)
{
$this->totalValCuTvaProduseFurnizorReturnate = $totalValCuTvaProduseFurnizorReturnate;
}
public function toArray()
{
return [
'totalValoare' => $this->getTotalValoare(),
'costAdaos' => $this->getCostAdaos(),
'totalTvaNeex' => $this->getTotalTvaNeex(),
'totalValCuTva' => $this->getTotalValCuTva(),
'totalValoareCantitateNegativaProduseFacturate' => $this->getTotalValoareCantitateNegativaProduseFacturate(),
'costAdaosCantitateNegativaProduseFacturate' => $this->getCostAdaosCantitateNegativaProduseFacturate(),
'totalTvaNeexCantitateNegativaProduseFacturate' => $this->getTotalTvaNeexCantitateNegativaProduseFacturate(),
'totalValCuTvaCantitateNegativaProduseFacturate' => $this->getTotalValCuTvaCantitateNegativaProduseFacturate(),
'totalValoarePozitivaProduseFacturate' => $this->getTotalValoarePozitivaProduseFacturate(),
'costAdaosPozitivaProduseFacturate' => $this->getCostAdaosPozitivaProduseFacturate(),
'totalTvaNeexPozitivaProduseFacturate' => $this->getTotalTvaNeexPozitivaProduseFacturate(),
'totalValCuTvaPozitivaProduseFacturate' => $this->getTotalValCuTvaPozitivaProduseFacturate(),
'totalValoareProduseFurnizor' => $this->getTotalValoareProduseFurnizor(),
'costAdaosProduseFurnizor' => $this->getCostAdaosProduseFurnizor(),
'totalTvaNeexProduseFurnizor' => $this->getTotalTvaNeexProduseFurnizor(),
'totalValCuTvaProduseFurnizor' => $this->getTotalValCuTvaProduseFurnizor(),
'totalValoareProduseFurnizorReturnate' => $this->getTotalValoareProduseFurnizorReturnate(),
'costAdaosProduseFurnizorReturnate' => $this->getCostAdaosProduseFurnizorReturnate(),
'totalTvaNeexProduseFurnizorReturnate' => $this->getTotalTvaNeexProduseFurnizorReturnate(),
'totalValCuTvaProduseFurnizorReturnate' => $this->getTotalvalcutvaprodusefurnizorreturnate(),
];
}
}
Then the loop becomes dead simple:
<?php
$dataset = 'supplier_invoices';
$SupplierInvoice = new Dbm_Supplier($dataset);
$accumulator = new InvoiceTotalsAccumulator();
foreach ($invoices as $invoice)
{
$data = $SupplierInvoice->findFirst(['supplier_invoice_id' => $invoice['supplier_invoice_id']]);
$data = $data['results'];
$invoiceCalculus = new InvoiceSupplierCalculus($data['supplier_invoice_date'], $data['currency_rate']);
$products = $SupplierInvoice->getProductsForInvoice($invoice['supplier_invoice_id']);
foreach ($products as $product)
{
$calculus = $invoiceCalculus->getCalculus($product);
$accumulator->addProductCalculus(
$product['invoice_quantity'],
$product['product_quantity'],
$calculus['default_currency_value'],
$calculus['adaos_com'],
$calculus['tva_neex'],
$calculus['val_cu_tva']
);
}
}
If this were my project, I would probably create some sort of DTO class to set the values into and pass an instance of it to the addProductCalculus function instead of the 6 different parameters, but that's probably overkill.

How to Add HTML in controller Codeigniter?

My content controller in codeIgniter:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class AutoLoadDiv extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->load->view('ngoding/AutoLoad');
}
public function getData() {
$this->load->library('table');
$err = file_get_contents("application\logs\log.php");
$filestr = preg_replace(array('/(^|\R)ERROR\s*-\s*/', '/(^|\R)(.*?)\s*-->\s*/'), array('$1', '$1$2 '), $err);
$arraySpacing = nl2br($filestr);
$arr = explode("\n", $arraySpacing);
for ($i = count($arr)-1; $i >= 0; $i--) {
echo "<html><body><table><tr><td>$arr[$i];</td></tr></table></body>/html>";
}
}
}
I have a problem make table in controller , I want to print a table like this:
I have view :
https://codeshare.io/GqyWmk
To print table like in the image you need to change your code like this.
Assuming you have only 4 column in the file:
$output = "<html><body><table>"; // Keep this outside for loop to print only once.
var $j = 0;
for ($i = count($arr)-1; $i >= 0; $i--) {
if ($j % 4 == 0) {
$output.="<tr>";
}
$output.="<td>$arr[$i]</td>"; // Adding new row in your output varible.
if ($j % 4 == 0) {
$output.="</tr>";
}
++$j;
}
$output.="</table></body>/html>"; // This should also be outside because you want to close table, body and html only once.
echo $output; // Printing your final data.
You can modify this code as per your requirement;

For Loop Not Working in a Laravel Controller Class

In my Laravel project, I have a BusController.php file where I need to run a for() loop. However, the loop is not working. I also tried a blade for looping but have the same problem.
BusController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\Bus;
use App\Bus_type;
use App\Company;
use App\Http\Requests;
class BusController extends Controller
{
public function index()
{
$buses = Bus::all();
$bus_types = Bus_type::all();
$companies = Company::all();
return view('admin.adding_bus', compact('buses', 'bus_types', 'companies'));
}
public function store(Request $request)
{
$bus = new Bus;
$bus->company_name = $request->company_name;
$bus->bus_type = $request->bus_type;
$bus->bus_number = $request->bus_number;
$bus->no_of_rows = $request->no_of_rows;
$bus->no_of_columns = $request->no_of_columns;
$seats = "";
for ($i = 1; $i <= ($request->no_of_rows * $request->no_of_columns); $i++) {
$seats = $seats . "b";
}
$bus->seats = $seats;
$bus->save();
$buses = Bus::all();
$bus_types = Bus_type::all();
$companies = Company::all();
return view('admin.adding_bus', compact('buses', 'bus_types', 'companies'));
}
}
Make sure you have validated the data you received from the Request. Because if you don't the loop will be fail since the loop condition will always be false.
And to test it, here's what I do:
$seats = "";
$num_cols = 2;
$num_rows = ''; // assume you don't validate the request, so this can receive empty string too
// $num_rows = 0; // will output the same as above
for($i = 1;$i<=($num_cols * $num_rows);$i++)
{
$seats = $seats."b";
}
var_dump($seats);
Output:
string(0) ""
And here it is working one:
$seats = "";
$num_cols = 2;
$num_rows = 20; // correctly validated as integer and must be more than 0 because you're doing multiplication here in the following loop
for($i = 1;$i<=($num_cols * $num_rows);$i++)
{
$seats = $seats."b";
}
var_dump($seats);
Output:
string(40) "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"

Doctrine batch inserting uses 2GB of Ram

I am trying to insert approximately 200k of records with Symfony2 and Doctrine via Doctrine Fixtures Bundle. I am using flush and clear but at the end script uses 1.8 GB of RAM.
This is the class that loads SmartMeter entities into database:
<?php
namespace HTEC\SmartMeteringAPIBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use HTEC\SmartMeteringAPIBundle\Entity\SmartMeter;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class LoadSmartMeterData extends AbstractFixture implements FixtureInterface, ContainerAwareInterface, OrderedFixtureInterface
{
static $NUMBER_OF_SMART_METERS = 0;
static $MAX_NUM_OF_SM_PER_CONC = 500;
/**
* #var ContainerInterface
*/
private $container;
public function getOrder()
{
return 10; // the order in which fixtures will be loaded
}
/**
* #inheritDoc
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* {#inheritDoc}
*/
public function load(ObjectManager $manager)
{
$numberOfUsers = LoadUserData::$NUMBER_OF_USERS;
$numberOfConcentrators = LoadConcentratorData::$NUMBER_OF_CONCENTRATORS;
$numberOfTariffs = LoadTariffData::$NUMBER_OF_TARIFFS;
$numberOfSmartMetersPerConcentrator = 0;
$smartMeter = null;
$concentrator = null;
$user = null;
$tariff = null;
$feeders = array();
$numberOfFeeders = 0;
$feedersRandomKey = array();
$isIpAddressDynamic = false;
$numberOfTransformerFeeders = 0;
$smartMeterType = 0;
$smartMeterProtocol = 0;
$modemType = 0;
$numberOfSmartMeters = 0;
echo "\n\nCreating Smart Meters. This could take a couple of minutes and could take approximately 2 GB of RAM \n\n...";
$startTime = time();
$smartMeterCount = 0;
$lastChunkNumber = 0;
$currentChunkNumber = 0;
$lastSmartMeterNumber = 0;
$smartMetersClearedCurrently = 0;
$concentratorSmartMeters = null;
for($i = 0; $i < LoadConcentratorData::$NUMBER_OF_CONCENTRATORS; $i++)
{
$concentrator = $manager->getRepository('SMAPIBundle:Concentrator')->find($i+1);
$numberOfSmartMetersPerConcentrator = rand(1, self::$MAX_NUM_OF_SM_PER_CONC);
$numberOfSmartMeters += $numberOfSmartMetersPerConcentrator;
for($c = 0; $c < $numberOfSmartMetersPerConcentrator; $c++)
{
$smartMeter = new SmartMeter();
$smartMeter->setSerialNumber(++$smartMeterCount);
$smartMeter->setConcentrator($concentrator);
$smartMeterType = rand(1,3);
switch($smartMeterType)
{
case 1:
$smartMeter->setType('DIRECT');
break;
case 2:
$smartMeter->setType('HALF');
break;
case 3:
$smartMeter->setType('INDIRECT');
break;
}
$user = $manager->getRepository('SMAPIBundle:User')->find(rand(1, $numberOfUsers));
$smartMeter->setCreatedBy($user);
$numberOfTransformerFeeders = $concentrator->getTransformerFeeders()->count();
$feeders = $concentrator->getTransformerFeeders()->toArray();
if($numberOfTransformerFeeders > 0)
{
$feedersRandomKey = array_rand($feeders, 1);
if(isset($feeders[$feedersRandomKey]))
{
$smartMeter->setFeeder($feeders[$feedersRandomKey]);
}
}
$smartMeter->setStatus(rand(0,2));
$tariff = $manager->getRepository('SMAPIBundle:Tariff')->find(rand(1, $numberOfTariffs));
$smartMeter->setTariff($tariff);
$smartMeterProtocol = rand(1,3);
switch($smartMeterProtocol)
{
case 1:
$smartMeter->setProtocol('DLMS');
break;
case 2:
$smartMeter->setProtocol('EURIDIS');
break;
case 3:
$smartMeter->setProtocol('IEC');
break;
}
$smartMeter->setModemSerialNumber(rand(1, 9000000000));
$smartMeter->setManufacture('MAN: ' . ($i + $c));
$modemType = rand(1,2);
if($modemType === 1)
{
$smartMeter->setModemType('PLC');
$smartMeter->setModemIndex(rand(1, 512));
}
else
{
$smartMeter->setModemType('GPRS');
$isIpAddressDynamic = rand(0,1);
if($isIpAddressDynamic === 1)
{
$smartMeter->setModemIpAddress(rand(1000000, 2000000));
}
else
{
$smartMeter->setModemPhoneNumber($this->getRandomIpAddressV4());
}
}
if(rand(0,1) === 1)
{
$smartMeter->setModemRepeaterNumber(rand(10000000, 90000000));
}
$manager->persist($smartMeter);
} // end of FOR numberOfSmartMetersPerConcentrator
// flush smart meters
$manager->flush();
$manager->clear();
$currentChunkNumber = ceil($smartMeterCount / 5000);
if($smartMeterCount > 5000 && $currentChunkNumber > $lastChunkNumber)
{
$lastChunkNumber = $currentChunkNumber;
if($lastSmartMeterNumber > 0)
{
$smartMetersClearedCurrently = $smartMeterCount - $lastSmartMeterNumber;
}
else
{
$smartMetersClearedCurrently = $smartMeterCount;
}
echo "\n\nFlushing and clearing " . number_format($smartMetersClearedCurrently, 0, ',', '.') . " Smart Meters.\nTotal memory used after flush and clear: " . number_format(((memory_get_usage(true) / 1024) / 1024), 2, ',', '.') . " Megabytes\n\n...";
$lastSmartMeterNumber = $smartMeterCount;
}
}// end for NUMBER_OF_CONCENTRATORS
$manager->flush();
$manager->clear();
unset($concentrator);
unset($smartMeter);
unset($tariff);
echo "\n\n-------------------------------------------\n\n";
echo "\n\nTotal memory used after final flush and clear of Smart Meters: " . number_format(((memory_get_usage(true) / 1024) / 1024), 2, ',', '.') . " Megabytes\n\n...";
echo "\n\nCreating Smart Meters complete. Created " . number_format($numberOfSmartMeters, 0, ',', '.') . " Smart Meters.\n\n";
$durationSeconds = (time() - $startTime);
$durationMinutes = $durationSeconds / 60;
$secondsRemainder = $durationSeconds % 60;
echo "\n\nTotal duration time: " . ceil($durationMinutes) . " minutes and " . $secondsRemainder . " seconds.\n\n\n";
self::$NUMBER_OF_SMART_METERS = $numberOfSmartMeters;
}
public function getRandomIpAddressV4()
{
return rand(1, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255);
}
}
On approximately 5000 records I am calling flush and clear but it seams that no memory is released.
Are there recommendations about how to prevent Doctrine from using too much RAM during batch tasks?
If it is a command, try running it with the option --no-debug. Or, you can disable the logger by calling $manager->getConnection()->getConfiguration()->setSQLLogger(null); at the beginning of your loadfunction.
Either way disabling the logger saves quite a lot of memory during Doctrine batch tasks.

PHP average calculator not displaying results properly

I'm creating a php calculator that needs to use the following classes, then print off the users name and the average score they achieved. This is the code I have so far, but it's not displaying correctly, it's saying there are missing arguments and undefined variables but i'm not sure where i've gone wrong!
<?php
class person {
public $name;
}
class student extends person {
function student ($name, $grade1, $grade2) {
if(is_numeric($grade1) && is_numeric($grade2)){
$grades = array($grade1, $grade2);
}
elseif (is_numeric($grade1)) {
$grade2 = 0;
}
else {
$grade1 = 0;
}
}
function average ($grades) {
$length = count($grades);
$total = 0;
for ($i = 0; $i < $length; $i++) {
$total = $total + $grades[i];
}
$average = $total / $length;
return $average;
}
}
$person1 = new student ($_POST['firstName'], $_POST['firstGrade1'], $_POST['firstGrade2']);
$person2 = new student ($_POST['secondName'], $_POST['secondGrade1'], $_POST['secondGrade2']);
$person3 = new student ($_POST['thirdName'], $_POST['thirdGrade1'], $_POST['thirdGrade2']);
echo "<br/> $person1->name" . "achieved an average of" . "$person1->average();";
echo "<br/> $person2->name" . "achieved an average of" . "$person2->average();";
echo "<br/> $person3->name" . "achieved an average of" . "$person3->average();";
?>
ERROR MESSAGES:
Warning: Missing argument 1 for student::average(), called in C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\my portable files\Exercise 4\average.php on line 40 and defined in C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\my portable files\Exercise 4\average.php on line 22
Notice: Undefined variable: grades in C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\my portable files\Exercise 4\average.php on line 23
Warning: Division by zero in C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\my portable files\Exercise 4\average.php on line 30
You don't appear to be returning that $grades variable. It's probably not defined because you aren't returning anything.
Your method:
function student ($name, $grade1, $grade2) {
if(is_numeric($grade1) && is_numeric($grade2)){
$grades = array($grade1, $grade2);
}
elseif (is_numeric($grade1)) {
$grade2 = 0;
$grades = array($grade1, $grade2);
}
else {
$grade1 = 0;
$grades = array($grade1, $grade2);
}
return $grades
}
Will need to look more like that. You'll also want to actually add grade1 and grad2 to your returned array in your alternate conditions.
The following is the classes enhanced. You will notice that they have constructors and functions to request variables. Private variables are usually the preferred method as they are protected and therefore cannot be modified outside the class.
class person {
private $name = "";
public function __construct ($nameV) {
$this->name = $nameV;
}
public function getName() {
return $this->name;
}
}
class student extends person {
private $grades;
public function __construct ($name, $grade1, $grade2) {
parent::__construct($name);
if ( ! is_numeric($grade1)) { $grade1 = 0; }
if ( ! is_numeric($grade2)) { $grade2 = 0; }
$this->grades = array($grade1, $grade2);
}
public function average () {
$length = count($this->grades);
$total = 0;
for ($i = 0; $i < $length; $i++) {
$total = $total + $this->grades[$i];
}
$average = $total / $length;
return $average;
}
}
The export code is then simply:
echo "<br/>" . $person1->getName() . " achieved an average of " . $person1->average();
echo "<br/>" . $person2->getName() . " achieved an average of " . $person2->average();
echo "<br/>" . $person3->getName() . " achieved an average of " . $person3->average();
Due to not having the form, I tested with the following data:
$person1 = new student ("XYZ", 1, 2);
$person2 = new student ("XYZ2", 100, 20);
$person3 = new student ("XYZ3", 95, 94);
Which exported:
XYZ achieved an average of 1.5
XYZ2 achieved an average of 60
XYZ3 achieved an average of 94.5

Categories