Cannot get functions to execute - php

So if the last function ended up working. And I followed all of your instructions to the T, why is this function not working properly? I've looked over it for an hour, tried rewrite it over and over again and all I get is a 0 or no return.
function marketing () {
$newsold = $_POST['newsold'];
$usedsold = $_POST['usedsold'];
$carsSold = $newsold + $usedsold;
$AdSpend = $carsSold * 275;
echo "You shoud spend roughly $AdSpend per year on advertising";
}
marketing();

You echo the values inside the function:
not:
echo "$autoProfit";
but,
<?php
function autoProfits () {
$usedprofit = 1527;
$newprofit = 800;
$newsold = $_POST['newsold'];
$usedsold = $_POST['usedsold'];
$uprofit = $usedsold * $profitused;
$nprofit = $newsold * $profitnew;
$autoProfit = $uprofit + $nprofit;
}
autoProfits();
?>
Take close att with the curly brace where to be placed.

Several things with your code:
1) By default, a form will post with GET and not POST. So either change your PHP variables to $_GET OR change your form's method to $_POST. I prefer to change the method.
<form action="calc.php" method="POST">
2) You're missing a curly brace on your function:
function makeProfit () {
if ($profit >=0) {
echo "Your company is making a profit.";
} else {
echo "Your company is not making a profit.";
}
}
3) In your function adSpend(), you should invert the line for $carsSold.
4) You have used upper and lower-case characters interchangeably in your variable names ($usedSold vs $usedsold). PHP variables are case-sensitive.
5) The "+" operator when used to combine a string and integer may work, but it would be better not to put integers in quotes.
5b) Using a comma will cause PHP to not recognize your variable as a number, so use $profitUsed = 1527; instead of $profitUsed = "1,527";
6) Your variables at the top of a PHP file are not GLOBAL. You'll either need to convert them to global variables, or (I prefer) send them as parameters to your function. An example of the corrected adSpend():
function adSpend ($newSold = 0, $usedSold = 0) {
$adSpendPerCar = 275;
$carsSold = $newSold + $usedSold;
$adSpend = $carsSold * $adSpendPerCar;
echo $AdSpend;
}
adSpend($newSold, $usedSold);
7) Finally, when you expect an integer from user input, you'd be best to verify that you have an integer. There are a lot of ways to do this, one simple method is to do something like this:
$newSold = intval($_POST['newsold']);
$usedSold = intval($_POST['usedsold']);
Edit Change your variables $profitused for $usedprofit and $profitnew for $newprofit
function autoProfits () {
$usedprofit = 1527;
$newprofit = 800;
$newsold = $_POST['newsold'];
$usedsold = $_POST['usedsold'];
$uprofit = $usedsold * $usedprofit;
$nprofit = $newsold * $newprofit;
$autoProfit = $uprofit + $nprofit;
echo $autoProfit;
}

function makeProfit () {
if ($profit >=0) {
echo "Your company is making a profit.";
} else {
echo "Your company is not making a profit.";
}
}
This function is missing the last '}' (curly bracket)
But you should also be sure when calling adSpend(), that the variables you're trying to access is set, else you won't get anything out of it.
Since you've made that setup, then you should be calling the functions right after you've set all the variables, for anything to work.

You're using undefined variables on the products. You defined $usedprofit and $newprofit but you're multiplying $profitused and $profitnew. Since they're not defined, PHP assumes they're 0.

Related

PHP OO - Associative array of object instances, resetting on each click

My first ever question on here as I'm completely stuck, so apologies if I leave out any key information - please let me know!
I am creating a PHP Battleships game and trying to use full OO. I'm really close, however, an array for one of my classes does not hold any updates I make to it.
First off, I dynamically
created a HTML table with an onclick event - which passes the coordinates to a JS function.
I then make an AJAX call in jQuery:
function shotFired(row, column) {
var coords = {
x: row,
y: column
};
$.post("data/game_controller.php", {
jsonCoords: JSON.stringify(coords)
}, function(results) {
console.log(results)
console.log(results[4])
var playerShotResult = results[0];
var computerShotX = results[1] + 1;
var computerShotY = results[2] + 1;
var computerShotResult = results[3];
var positionsClicked = document.getElementById("computer_" + row + "," + column)
switch (playerShotResult) {
case "MISS":
positionsClicked.classList.add("miss");
break;
case "HIT":
positionsClicked.classList.add("hit");
break;
case "Already Hit":
document.getElementById("outputMessage").innerHTML = result
break;
default:
console.log("Player shot defaulted");
}
}, "json")
I then use game_controller.php to handle the request and call shotFired:
<?php
session_start();
require("../classes/Game.class.php");
if (isset($_POST['jsonCoords'])) {
if (isset($_SESSION['newGame'])) {
$game = unserialize($_SESSION['newGame']);
$coords = json_decode($_POST['jsonCoords']);
$results = $game->shotFired($coords->x, $coords->y);
echo json_encode($results);
}
}
shotFired from the Game.php Class file, gets an instance of the Fleet class called computer, and runs the checkPosition function:
public function shotFired($x, $y)
{
$computer = $this->getComputer();
$playerHit = $computer->checkPosition(($x - 1), ($y - 1));
$computerGrid = $computer->getBattleshipsGrid();
$computerHit = $this->simulateComputerShot();
return [$playerHit, $computerHit[0], $computerHit[1], $computerHit[2], $computerGrid];
}
checksPosition checks the State of the Position instance in the BattleshipGrid array, and then attempts to update the array with a H or M - using a standard setter method:
public function checkPosition($x, $y): string
{
$positionObj = $this->battleshipsGrid["(" . $x . "," . $y . ")"];
$positionState = $positionObj->getState();
if ($positionState == "#") {
$positionObj->setState("M");
return "MISS";
} elseif ($positionState == "M" || $positionState == "H") {
return "Already Fired";
} else {
$positionObj->setState("H");
return "HIT";
}
}
For reference, I set the Battleships board in the constructor for Fleet.php:
// Populate associative array with instances of position
for ($y = 0; $y < $gridSize; $y++) {
for ($x = 0; $x < $gridSize; $x++) {
$coordinates = "(" . $x . "," . $y . ")";
$this->battleshipsGrid[$coordinates] = new Position($x, $y);
}
}
It works directly after it has been set - however, on the next onclick event, the H or M value is reset to it's previous value?
Seen here in console output
After a couple of hours, the closest I've come to is passing byRef in the setState function (didn't make a difference).
I've seen some notes on array_map, but I'm not sure this is what I'm looking for?
For ref, this is how I output the battleshipGrid to the console:
public function getBattleshipsGrid()
{
$readableGrid = "";
$grid = $this->battleshipsGrid;
foreach ($grid as $coordsID => $positionObj) {
$readableGrid .= "\n" . $coordsID . ": " . $positionObj->getState();
}
return $readableGrid;
}
Apologies for the long post, but I didn't want to leave anything out. Any and all help would be extremely appreciated!
Many thanks
It looks like you're not saving the state of the coordinates of the hits. If you are using the eloquent model, and setState is changing the attribute's value, make sure that you call $positionObj->save() as php does not save state on each ajax request. You will need to use a database or some sort of storage to have the server 'remember' that you clicked a specific location.

avoid repeating variable due to undefined variable error

I'm trying to make a profile completion progress, which shows the percentage of how much a user has completed his profile settings. If a user has filled in a field, he receives +15 or +5, however, if the field is not filled in he receives +0.
the code I did is really bad, with variable repetitions, I wanted to know if you knew a cleaner way to do this.
if (!empty($user->avatar)) {
$avatar = 15;
} else { $avatar = 0; }
if (!empty($user->copertina)) {
$copertina = 15;
} else { $copertina = 0; }
// dati personali
if (!empty($user->name)) {
$name= 5;
} else { $name = 0; }
if (!empty($user->last_name)) {
$last_name = 5;
} else { $last_name = 0; }
[...]
if (!empty($user->biografia)) {
$biografia = 5;
} else { $biografia = 0; }
$personal = $avatar+$copertina+$name+$last_name+$sesso+$nascita;
$gaming = $steam+$battlenet+$xbox+$playstation+$switch+$uplay+$origin+$ds;
$social = $twitter+$facebook+$biografia;
$punti = $personal+$gaming+$social;
how do I remove all the others {$ variable = 0}?
You can't really, since you want the value to be a number, and not "undefined". You could initialize your variables to 0 like in this answer stackoverflow.com/questions/9651793/….
If you want to get into type comparisons for null variables, check php.net/types.comparisons. I would just initialize the variables to 0 and remove all the else.
OR...
modify your $user object to have all these variables in an array ($key:$value). You can then initialize the array to 0 all over, and modify it. Adding a new profile value would be easy, and adding array values is quick.
This snippet :
if (!empty($user->avatar)) {
$avatar = 15;
}
else {
$avatar = 0;
}
is semantically equivalent to :
$avatar = (bool)$user->avatar * 15;
Explanation:
Non-empty field gets converted to true and empty string or null gets converted to false
Because we do multiplication php true/false values gets converted to 1/0
So after multiplication you get 15 * 1 or 15 * 0 - depending if your field was used or not.

PHP, Function breaks when numbers are passed in as arguements

I have the following function which works well, if I call it with only the first parameter:
function max_months($vehicle_age,$max_peroid,$no_older) {
$tot_age_in = $vehicle_age + 315360000;
while ($tot_age_in > 536467742) {
$tot_age_in = $tot_age_in - 31536000;
if ($tot_age_in < 536467742) {
$max_payback = floatval($tot_age_in - $vehicle_age);
$max_payback = seconds_to_month($max_payback);
break;
}
}
return $max_payback;
}
However, when I alter this function and pass in the numbers seen above as
parameters, the function breaks.
function max_months($vehicle_age,$max_peroid,$no_older) {
$tot_age_in = $vehicle_age + $max_peroid;
while ($tot_age_in > $no_older) {
$tot_age_in = $tot_age_in - $max_peroid;
if ($tot_age_in < $no_older) {
$max_payback = floatval($tot_age_in - $vehicle_age);
$max_payback = seconds_to_month($max_payback);
break;
}
}
return $max_payback;
}
I'm calling the function like so:
$max_payback = max_months($vehicle_age,315360000,536467742);
$vehicle_age is set to 288897248
So in the first instance I return a valid number, however in the second instance I return false, even though the numbers are the same. Could anyone suggest why this might be? Cheers
$max_payback is not always initialized. It's a good habit to always initialize the return value..
It is highly likely that you run out of the PHP_INT_MAX value, you can check the maximum integer value by doing
echo PHP_INT_MAX;
If the variable is bigger than the INT_MAX, it is treated like a float value. This means, that you have to deal with floating point imprecision problems. And instead of checking <, == or >, you should check for a certain range epsilon around the value to be checked.
By changing your code like below, the problem is likely solved:
function max_months($vehicle_age,$max_peroid,$no_older) {
$e = 0.0001;
$tot_age_in = $vehicle_age + $max_peroid;
while ($tot_age_in > $no_older-$e) {
$tot_age_in = $tot_age_in - $max_peroid;
if ($tot_age_in < $no_older+$e) {
$max_payback = floatval($tot_age_in - $vehicle_age);
$max_payback = seconds_to_month($max_payback);
break;
}
}
return $max_payback;
}
See also: http://php.net/manual/en/language.types.integer.php
You did not have that problem when you used the hard coded numbers because they are treated like constants and therefore you did not have the float problem.

How can I set a variable variable from within a function in PHP?

I am making a form, some of which is optional. To show the output of this form, I want to be able to check whether a POST variable has contents. If it does, the script should make a new normal PHP variable with the same value and name as the POST variable, and if not it should make a new normal PHP variable with the same name but the value "Not defined". This is what I have so far:
function setdefined($var)
{
if (!$_POST[$var] == "")
{
$$var = $_POST[$var]; // This seems to be the point at which the script fails
}
else
{
$$var = "Not defined";
}
}
setdefined("email");
echo("Email: " . $email); // Provides an example output - in real life the output goes into an email.
This script doesn't throw any errors, rather just returns "Email: ", with no value specified. I think this is a problem with the way I am using variable variables within a function; the below code works as intended but is less practical:
function setdefined(&$var)
{
if (!$_POST[$var] == "")
{
$var = $_POST[$var];
}
else
{
$var = "Not defined";
}
}
$email = "email"; // As the var parameter is passed by reference, the $email variable must be passed as the function argument
setdefined($email);
Why don't you do it this way:
function setdefined($var)
{
if (isset($_POST[$var]) && !empty($_POST[$var]))
{
return $_POST[$var];
}
else
{
return "Not defined";
}
}
$email = setdefined('email');
echo("Email: " . $email);
The variable you create in first example is only available inside the function
You could make that unknown variable submitted by possibly malicious user, global one. To do so, add this to the start of your function:
global $$var ;
This is not only ugly, but maybe unsafe too.

unique random id

I am generating unique id for my small application but I am facing some variable scope problem. my code-
function create_id()
{
global $myusername;
$part1 = substr($myusername, 0, -4);
$part2 = rand (99,99999);
$part3 = date("s");
return $part1.$part2.$part3;
}
$id;
$count=0;
while($count == 1)
{
$id;
$id=create_id();
$sqlcheck = "Select * FROM ruser WHERE userId='$id';";
$count =mysql_query($sqlcheck,$link)or die(mysql_error());
}
echo $id;
I dont know which variable I have to declare as global
That doesn't look like a variable scope problem, it looks like a simple variable assign problem:
$count=0;
while($count == 1)
{
This block will clearly never execute.
Further, please use a boolean with a good name when doing boolean checks. It reads so much cleaner. i.e.:
function isUniqueUserID($userIDToCheck)
{
$sqlcheck = "Select * FROM user WHERE userId='$userIDToCheck';";
$resource = mysql_query($sqlcheck)or die(mysql_error());
$count = mysql_fetch_assoc($resource);
if( count($count) > 0)
{return false;}
return true;
}
$userIDVerifiedUnique = false;
while(! $userIDVerifiedUnique )
{
$userIDToCheck = create_id();
$userIDVerifiedUnique = isUniqueUserID($userIDToCheck );
}
Note that mysql_query will use the last used connection if you don't specify a link:
http://us2.php.net/mysql_query
No need to make it global.
in adition to Zak's answer i'd pass the username into the function instead of using globals
function create_id($username)
{
$part1 = substr($username, 0, -4);
$part2 = rand (99,99999);
$part3 = date("s");
return $part1.$part2.$part3;
}
also
//$id; no need for this
$count=1; // this bit
while($count == 1) // not sure what's going on
{
//$id; again same thing no need for this
$id=create_id($myusername);
edit: now that i think of it: how do you expect to find "Select * FROM ruser WHERE userId='$id';"? A Select query is used to find something specific, your username is so random, i think the likely hood of actually successfully getting a record is 1 in a bajillion.
edit2 whoops, i see the whole point is to get a unique username... O_O
In addition to the others:
$count =mysql_query($sqlcheck,$link)or die(mysql_error());
mysql_query doesn't return a record count but, rather, a resource.
mysql_query

Categories