Iterating variables in PHP not working - php

I've done hours of research on this now, so I believe I'm not repeating, even though this seems like it would have a simple solution.
I have an HTML form sending values to PHP, where it takes the value, and sets them all to a variable. When I submit the values and load the PHP, it completely breaks as if there is a syntax problem, but I can't find anything obvious.
I'm setting the variables from POST like so:
$ital1=$_POST['checkbox1'];
$bold1=$_POST['checkbox2'];
$ital2=$_POST['checkbox3'];
$bold2=$_POST['checkbox4'];
I'm then using these variables with simplexml to write to an xml document for databasing. Here's a snippet of that:
$xml = simplexml_load_file('settings.xml');
function loops()
{
$italvar = (eval('return $' . "ital{$string}"));
$boldvar = (eval('return $' . "bold{$string}"));
$alertvar = (eval('return $' . "alerttitle{$string}"));
$pagevar = (eval('return $' . "page{$string}n"));
$colorvar = (eval('return $' . "colorset{$string}"));
$string = strval($i);
for($i=1; $i<21; $i++)
{
if($xml->settings->checkbox->"ital{$string}" == $empty && $italvar == "on")//ITAL1
{
$xml->settings->checkbox->"ital{$string}" = $italvar;
}
else if($italvar == $empty && $xml->settings->checkbox->"ital{$string}" == "on")
{
$xml->settings->checkbox->"ital{$string}" = $empty;
}
else
{
continue;
}
}
$xml->asXML('settings.xml');
This is just a piece of the function, but the rest is basically this repeated for different types of variables. I know the issue is within the loops function as when I delete loops(), the PHP at least loads some echos at the top of the doc.
I'm not sure what in here is breaking. I'm guessing it's the syntax with how I'm combining and iterating variables, which explains the title.
So my questions is this. How do I combine strings and variables correctly?
$italvar = (eval('return $' . "ital{$string}"));
$string = strval($i);
In this instance I want the end result to be $ital#, # being the current iteration of the forloop, so I can correctly write to xml the value of the set variable from $_POST as shown at the top.
"ital{$string}"
$string = strval($i);
And here I just want it to be a string such as ital1, then ital2, as that's what the nodes are called in the xml. I'm sure what I'm doing wrong is very obvious, but I'm very new to PHP and I can't seem to figure it out. Thank you very much in advance for any input!

You have a $_POST array. Use it.
for( $i=1; $i<=20; $i++) {
$ital = $_POST['checkbox'.($i*2-1)];
$bold = $_POST['checkbox'.($i*2)];
// now do stuff with `$bold` and `$italic`
}

Related

How to affect a string to a variable without redefining it

I'm working on a project, and it has a bunch of variables for some links that I define. But I want to add a string at the end of those variable only if I got some GET parameters. The thing is I don't want to have another huge amount of variables and I want to have the same name for the variables. After some research, I came with this operator .= which is perfect for me. I also made a for loop it works well for the variable value, but I don't have the same name.
Here is what I got:
$homeLink = $wURL.'government/'.$job.'/';
$databaseLink = $wURL.'government/'.$job.'/search/database';
$overviewLink = $wURL.'government/'.$job.'/overview';
// Other variables
if (!isset($_SESSION['steamid']) && isset($_GET['uID']) && isset($_GET['uToken'])) {
// redefine the variables like this:
$homeLink .= '?uID='.$userinfoVlife['id'].'&uToken='.$userinfoVlife['websiteMDP'];
/*
OUTPUT: $wURL.'government/'.$job.'/'.'?uID='.$userinfoVlife['id'].'&uToken='.$userinfoVlife['websiteMDP']
*/
// The for loop:
$arr = array($homeLink,$databaseLink,$overviewLink);
$nb = count($arr);
for ($i=0; $i < $nb ; $i++) {
$arr[$i] .= '?uID='.$userinfoVlife['id'].'&uToken='.$userinfoVlife['websiteMDP'];
echo $arr[$i]."<br>";
// have the same output that above but I have to call my variables with $arr[<a number>];
}
}
The thing is I don't want to have another huge amount of variables and I want to have the same name for the variables, any ideas on how I can proceed?
First, your 2 last links are actually both based on the first one, $homeLink:
$homeLink = $wURL.'government/'.$job.'/';
$databaseLink = $homeLink.'search/database';
$overviewLink = $homeLink.'overview';
then why not build the parameter string and then append it?
$homeLink = $wURL.'government/'.$job.'/'
$paramString = '';
if (!isset($_SESSION['steamid']) && isset($_GET['uID']) && isset($_GET['uToken'])) {
$paramString = '?uID='.$userinfoVlife['id'].'&uToken='.$userinfoVlife['websiteMDP'];
}
$databaseLink = $homeLink.'search/database'.$paramString;
$overviewLink = $homeLink.'overview'.$paramString;
$homeLink .= $paramString;
I don't get why you want to store your URLs in an array, these are different URLs, thus to be used in different contexts, having all of them in one array is of course possible but doesn't bring any value, in my opinion.
To conclude, if $userinfoVlife['websiteMDP'] contains a readable password, you definitely have a problem in your application architecture: it's very bad practice to handle raw passwords and it's even worse to pass it in the URL.

PHPExcel conditionally formatting a range with a formula

I have the following code:
$vOffset = 2;
$offset = 6;
$formatRows = 100;
$formatColumns = 100;
//set conditional formatting in place
for($row=$vOffset;$i<$formatRows;$row++){
for($col=$offset+1;$col<$formatColumns;$col+3){
//prepare conditional styles
//if verbal is bigger
$conditionalStyle_RED = new PHPExcel\Style_Conditional();
$conditionalStyle_RED->setConditionType(PHPExcel\Style_Conditional::CONDITION_CELLIS);
$conditionalStyle_RED->addCondition(
"=" . $this->coordinates($col, $row) . " > " . $this->coordinates($col+1,$row)
);
$conditionalStyle_RED->getStyle()->getFont()->getColor()->setARGB(PHPExcel\Style_Color::COLOR_RED);
array_push($conditionalStyles, $conditionalStyle_RED);
$this->getActiveSheet()
->getStyle($this->coordinates($col, $row) . ':' . $this->coordinates($col+1, $row))
->setConditionalStyles($conditionalStyles);
}
}
Where I attempt to set a conditional style with the formula akin to:
=A1 > A3
It isn't yet working. Anyone know how to accomplish this?
Quite a late response, but I have been looking through the internet for a similar issue. Eventually I solved it. Incase people in the future might come across this problem I will note down a few things.
I have been struggling with the same kind of issue and I managed to solve it. What you want is to insert a formula into the conditional formatting. This sounds trickier than it actually is.
For your specific piece of code this should most likely work.
$vOffset = 2;
$offset = 6;
$formatRows = 100;
$formatColumns = 100;
//set conditional formatting in place
for($row=$vOffset;$i<$formatRows;$row++){
for($col=$offset+1;$col<$formatColumns;$col+3){
//prepare conditional styles
//if verbal is bigger
$conditionalStyle_RED = new PHPExcel\Style_Conditional();
$conditionalStyle_RED->setConditionType(PHPExcel\Style_Conditional::CONDITION_EXPRESSION);
$conditionalStyle_RED->setConditions(array("(" . $this->coordinates($col, $row) . " > " . $this->coordinates($col+1,$row) . ")"));
$conditionalStyle_RED->getStyle()->getFont()->getColor()->setARGB(PHPExcel\Style_Color::COLOR_RED);
array_push($conditionalStyles, $conditionalStyle_RED);
$this->getActiveSheet()
->getStyle($this->coordinates($col, $row) . ':' . $this->coordinates($col+1, $row))
->setConditionalStyles($conditionalStyles);
}
}
The "condition_expression" is used in order to place a formula inside a conditional format. As far as I was able to figure out the only way to implement a formula is by using the "setConditions". With this you can give an array of strings, with each string being a formula.
In your code this would result in the color of red when the first coordinate is bigger than the second one.
Now back to your code, I haven't tested it so you might want to tweak a few values, but this should at least push you towards the right direction. Good luck mate!

Using arrays with strings with a while loop

I am writing some code to create fields automatically, which will save me a load of time. I have got most of my code working, but I have came across one error with the code, which is preventing me from achieving my final goal.
The code is as follows:
while ($i <= $numFields) {
$type = "\$field{$i}_Data['type']";
$name = "\$field{$i}_Data['name']";
$placeholder = "\$field{$i}_Data['placeholder']";
$value = "\$field{$i}_Data['value']";
echo '<input type="'.$type.'" name="'.$name.'" placeholder="'.$placeholder.'" value="'.$value.'">';
$i++;
}
The $numFields variable is defined at the top of my script, and I have worked out that it is something to do with how I am setting the variables $type, $name etc.
The end result is to create inputs depending on properties set in variables at the top of the script, The only issue I am having is with the settings of the variables, as said above.
If any extra code/information is needed, feel free to ask.
Thank you.
NOTE - There is no physical PHP error, it's purely an error with this:
"\$field{$i}_Data['value']";
There are a few ways we could write this one out, but they are all extensions of variable expansion and/or variable-variables.
Basically, we just need to put the variable name in a string and then use that string as the variable (much like you're currently doing with $i inside the string):
$type = ${"field{$i}_Data"}['type'];
$name = ${"field{$i}_Data"}['name'];
// ...
However, if you don't mind an extra variable, this can be written more cleanly by saving it like so:
$data = ${"field{$i}_Data"};
$type = $data['type'];
$name = $data['name'];
// ...

Possible to overide a foreach variable parameter within itself?

I have made a small script which uses the Twitch API. The API only allows a maximum of 100 results per query. I would like to have this query carry on until there are no more results.
My theory behind this, is to run a foreach or while loop and increment the offset by 1 each time.
My problem however, is that I cannot change the foreach parameters within itself.
Is there anyway of executing this efficiently without causing an infinite loop?
Here is my current code:
<?php
$newcurrentFollower = 0;
$offset=0;
$i = 100;
$json = json_decode(file_get_contents("https://api.twitch.tv/kraken/channels/greatbritishbg/follows?limit=25&offset=".$offset));
foreach ($json->follows as $follow)
{
echo $follow->user->name . ' (' . $newcurrentFollower . ')' . "<br>";
$newcurrentFollower++;
$offset++;
$json = json_decode(file_get_contents("https://api.twitch.tv/kraken/channels/greatbritishbg/follows?limit=25&offset=".$offset));
}
?>
Using a While loop:
while($i < $total)
{
$json = json_decode(file_get_contents("https://api.twitch.tv/kraken/channels/greatbritishbg/follows?limit=25&offset=".$offset));
echo $json->follows->user->name . ' (' . $newcurrentFollower . ')' . "<br>";
$newcurrentFollower++;
$offset++;
$i++;
}
Ends up echoing this (No names are successfully being grabbed):
Here is the API part for $json->follows:
https://github.com/justintv/Twitch-API/blob/master/v2_resources/channels.md#get-channelschannelfollows
You can use this:
$offset = 0;
$count = 1;
do {
$response = json_decode(file_get_contents(
'https://api.twitch.tv/kraken/channels/greatbritishbg/follows?limit=100&offset=' . $offset
));
foreach($response->follows as $follow) {
echo $follow->user->name . ' (' . ($count++) . ')' . "</br>";
}
$offset+=25;
} while (!empty($response->follows));
You want to use a while loop here, not just a foreach. Basically:
while (the HTTP request returns results)
{
foreach ($json->follows as $follow)
{
do stuff
}
increment offset so the next request returns the next one not already processed
}
The trickiest part is going to be getting the while condition right so that it returns false when the request gets no more results, and will depend on what the API actually returns if there are no more results.
Also important, the cleanest way would be to have the HTTP request occur as part of the while condition, but if you need to do some complicated computation of the JSON return to check the condition, you can put an initial HTTP request before the loop, and then do another request at the end of each while loop iteration.
The problem is you're only capturing the key not the value. Place it into a datastructure to access the information.
Honestly I find a recursive function much more effective than a iterative/loop approach then just update a datatable or list before the next call. It's simple, uses cursors, lightweight and does the job. Reusable if you use generics on it too.
This code will be in c#, however I know with minor changes you'll be able to get it working in php with ease.
query = //follower object get request//
private void doProcessFollowers(string query)
{
HTTPParse followerData = new HTTPParse(); //custom json wrapper. using the basic is fine. Careful with your cons though
var newRoot = followerData.createFollowersRoot(query); // generates a class populated by json
if (newRoot[0]._cursor != null)
{
populateUserDataTable(newRoot); //update dataset
doProcessFollowers(newRoot[0]._links.next); //recurse
}
}
Anyway - This just allows you to roll through the cursors without needing to worry about indexes - unless you specifically want them for whatever reason. If you're working with generics you can just reuse this code without issue. Find a generic example below. All you need to do to make it reuseable is pass the correct class within the <> of the method call. Can work for any custom class that you use to parse json data with. Which is basically what the 'createfollowerroot()' is in the above code, except that's hard typed.
Also I know it's in c# and the topic is php, with a few minor changes to syntax you'll get it working easily.
Anyway Hope this helped somebody
Generic example:
public static List<T> rootSerialize<T>(JsonTextReader reader)
{
List<T> outputData = new List<T>();
while (reader.Read())
{
JsonSerializer serializer = new JsonSerializer();
var tempData = serializer.Deserialize<T>(reader);
outputData.Add(tempData);
}
return outputData;
}

Removing last comma from out in PHP that is going into a javascript image pre-load script

Hi I have a javascript pre-load script that incorporates a php command to pre-load uploaded images for a future onClick action. Anyway I am having trouble removing the LAST comma from the last image the pre-load script pulls from.
Here is the script:
<div style="display:hidden">
<script type="text/javascript">
<!--//--><![CDATA[//><!--
var images = new Array()
function preload() {
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image()
images[i].src = preload.arguments[i]
}
}
preload(
<?php
for ($i = 0; $i < 6; $i++) {
if (!empty($imgs[$i])) {
echo "'http://www.samplegallery.com/upload/image.php?img_source_url=" . $imgs[$i] . "&img_resize_to=500',";
}
}
?>
)
//--><!]]>
</script>
</div>
Anyway, I need to find out how to remove the last comma from the last image that is uploaded. Not sure how to do this. Please help me! BTW... the images don't have an extension since they are linking to a php image script that resizes them and places them into a watermark. Hope you guys can help me figure!
Think the other way! the comma could be at the start and then you remove it from the first one :)
if (!empty($imgs[$i])) {
$comma = $i == 0? '' : ',';
echo $comma."'http://www.samplegallery.com/upload/image.php?img_source_url=" . $imgs[$i] . "&img_resize_to=500'";
}
This way doesn't matter if $i is equal to 5, 8 or 139871!
The easiest way to do it is using the php build in implode() function
<?php echo implode(',', $imgs); ?>
And if you want just the first 6 images, you can make an array like so
$imgs = array_slice($imgs, 0, 6);
So the whole thing must look like that:
preload(
<?php
$imgs = array_slice($imgs, 0, 6);
echo implode(',', $imgs);
?>
)
to remove the last comma from a string, just use this:
$string = rtrim($string, ",");
May I suggest a slightly different approach to your problem? Whenever you want to pass data to JavaScript, JSON is probably the thing you want to generate. json_encode() helps you with that. Your script could look like:
var urls = <?php echo json_encode(array_values($imgs)); ?>;
var images = [];
function preload(urls) {
for (var i = 0; i < urls.length; i++) {
var url = 'http://www.samplegallery.com/upload/image.php?img_source_url='
+ encodeURIComponent(urls[i])
+ '&img_resize_to=500';
images[i] = new Image();
images[i].src = url;
}
}
preload(urls);
please note that I've taken the liberty of adding missing semicolons and var declarations to keep your variables local. I have added the array_values() call to make sure you're passing a numerically indexed array, rather than an associative array that would have resulted in an object literal { ... } rather than an array literl [ ... ].
I have also moved the URL building to JavaScript, as I didn't see a reason to keep it in PHP. If you need this to be in PHP and want to avoid the "manual" loop, look into array_map().
Please also note that I'm running your URL fragment through encodeURIComponent() to properly escape whatever it is you're passing in.
A note on security: should your script at /upload/image.php accept arbitrary URLs (and or "local file resources"), consider white-listing the allowed domains and paths.
You could use a foreach...
<?PHP
if ($count = count($imgs)) {
foreach ($imgs as $key=>$img) {
echo "http://www.samplegallery.com/upload/image.php?img_source_url="
. $img . "&img_resize_to=500";
if ($key < $count-1) echo ",";
}
}
?>

Categories