PHP function returns unexpected values - php

Okay I'm new here and I have been trying to figure this out all day I have two functions one calling the other but my functions only returns the last value for example 29 when it should return multiple values. As wondering how can I fix this problem so that my functions return all the values.
Here is my PHP code.
function parent_comments(){
if(articles_parent_comments_info($_GET['article_id']) !== false){
foreach(articles_parent_comments_info($_GET['article_id']) as $comment_info){
$comment_id = filternum($comment_info['comment_id']);
reply_comment_count($comment_id);
}
}
}
function reply_comment_count($parent_id){
if(articles_reply_comments_info($_GET['article_id']) !== false){
foreach(articles_reply_comments_info($_GET['article_id']) as $reply_info){
$comment_id = filternum($reply_info['comment_id']);
$reply_id = filternum($reply_info['parent_id']);
if($parent_id === $reply_id){
reply_comment_count($comment_id);
}
}
}
return $comment_id;
}

You use recursivity to return your $comment_id. If I understand your needs, you want to get every reply id linked to one article id.
In reply_comment_count you return $comment_id but as it rescursively used and you don't keep the previous id returned you only get the last.
If you want to get numerous $comment_id instead of only one, I suggest you to return an array where you push $comment_id every time you find one. Something like that:
func parent_comments(){
loop in articles to get comment_id {
count_array = reply_comment_count(comment_id, count_array)
}
}
func reply_comment_count(parent_id, count_array) {
loop to get id linked to parent_id {
if id is an article {
count_array = reply_comment_count(id, count_array) #recursive call
}
else {
count_comment = count comment linked
count_array.push(count_comment)
}
}
return count_array # when you return your count_array due to recursive call it will be filled with every count, and not only the last
}
I hope this pseudo langage is clear for you. But as you only return the last count you found, you will only have this one.

Related

Count empty mysql columns in PHP

I'm trying to create a method that counts the empty mysql columns.
My code is as follows:
public function countCompletion() {
$userData = $this->find(Session::get('user'));
$userData = $this->_data;
$completion = 0;
foreach($userData as $item) {
if(empty($item)) {
$completion++;
}
}
die($completion);
}
The problem is, when I die $completion it just shows nothing, while it should show 2.
According to the documentation, when die (or exit) is called with an integer argument the argument is not printed but is instead passed back to the operating system as an exit code. To get the value to display you will need to return it, then print it from the calling routine.
first check with "echo" inside "foreach" to display column content then you can do a loop to incremente number of empty column
foreach($userData as $item) {
echo 'data: '.$item.'<br>';
if(empty($item)) {
$completion++;
}
}
bacause you have to verify that your function is executing successfully
you can use "var_dump()" also to test what variable contains
var_dump($completion);
die();

INSERT if doesn't already exist in database

I created a function that looks for all rows (records) in a specific column,
generates a random number and then checks if it already exists withing that column, if the generated random number exists restart the function (recursive)
if it doesn't exist then insert it as new.
$verifs = mysqli_query($conlink, 'SELECT verif FROM memebers');
$records = array();
while($record = mysqli_fetch_array($verifs,MYSQLI_NUM)) {
$records[] = $record[0];
}
function randomize(){
$rand= rand(1,5);
if(in_array($rand, $GLOBALS['records'])){
randomize();
}else{
return $rand;
}
}
mysqli_query($conlink, "INSERT INTO `memebers`(`verif`) VALUES (".randomize().")");
i expected that a number MUST be added EACH time i refresh my php page
and it was the case, but when i reach 3 or 4 records, refreshing the page doesn't add any ! so the return statement must prevent the function from being recursive.
am i having anything wrong with my logic
thanks
It appears to me that you are not using the callback function correctly. If you didn't know, when you use a function within a function, you actually have to pass that function inside the parameters. Functions that have a function in the parameter are called callback functions and you can read more about them in the following post: What is a callback function and how do I use it with OOP
I would then change your randomize function to the following code:
function randomize($callbackRandomize){
$rand= rand(1,5);
if(in_array($rand, $GLOBALS['records'])){
return $callbackRandomize($callbackRandomize);
}else{
return $rand;
}
}
and also change your last line of code to:
mysqli_query($conlink, "INSERT INTO `memebers`(`verif`) VALUES (".randomize('randomize').")");
Let me know if that worked for you.

Populating an Array with recursive function of a class

I'm getting stuck with maybe a simple question. I created a new class with many calculations inside. I have a recursive array to dynamically generate SQL from a Die result. When the result is between a given range, I'll have to do an extra operation.
I've got this multi-dimensional array to fill with the value of my dice, using an array of IDs as my first "key":
$this->multidim[$id_object][]
I was thinking about creating another function to populate it, but I'm unsure how to build it correctly. The specifications of this function I need are the following:
I need to call a function with the multidimensional array, and
If the result is 100, I need to re-roll the dice twice, and check the result again
$this->checkresult($id_obj, $die);
function checkresult($id_obj, $die)
{
if ($die == 100){
$rand1 = $this->launchDie(1, 100);
$rand2 = $this->launchDie(1, 100);
if($this->checkresult($array, $rand1)) {
if($this->checkresult($array, $rand2)) {
return 1;
}
}
} else {
if (!isset($array[$tiro])) {
$this->multidim[$id_obj][$die] = 1;
}
return 1;
}
}
Is this approach correct? I feel uncomfortable not returning a "real" value, but as I said I need to re-call that function recursively.
You can return the rolled value like this:
public function addResult($object_id, $result)
{
$this->multidim[$object_id][] = $result;
}
public function checkResult($object_id)
{
$roll = $this->launchDie(1, 100);
if ($roll == 100) {
$additionalRoll = $this->checkResult($object_id);
$this->addResult($object_id, $additionalRoll);
$roll = $this->checkResult();
}
return $roll;
}
And call it like this:
$this->addResult($object_id, $this->checkResult($object_id));
This way each time a 100 is rolled there will be two rolls instead of the one. Please note that this could go on forever (improbable, though ;)).
Also note that I changed the structure of your multidim array, as it made more sense to me that way, you may need to change that back if it doesn't match what you would like to achieve.

PHP sort array function

I have a table that consists of comments. Some of them are replies to other comments and have a value set in parent_commentid table. I'm trying to create a function that checks each element in a result set if there is a value in the parent_columnid and if so take the entire element and sort it inside the element with a comment_id that matches the parent_commentid of the current element in the iteration. This is what I've come up with so far.
function sort_comments($comments){
$result = array();
foreach($comments as $comment){
if(is_null($comment['parent_commentid'])) $result[] = $comment;
else{
$parent_comment = array_search($comment['parent_commentid'], $comments);
if($parent_array !== false) $result[$parent_comment][] = $comment;
}
}
}
array_search is not the function I'm looking for but is the closets thing I could think of. Im not sure where to go from here. Keep in mind also that there can exist replies to other replies.
You need to store the comments by their own id, so that you can reference them later:
function sort_comments($comments){
$result = array();
foreach($comments as $comment){
if(is_null($comment['parent_commentid'])){
$result[$comment['commentid']] = $comment;
}else{
$parent_comment = $result[$comment['parent_commentid']]
if($parent_comment)
$parent_comment[$comment['commentid']] = $comment;
else
// what happens in this case:
// parent_commentid set, but no such comment exists?
}
}
Note the $comment['commentid']. I don't know how you call the id of a comment (commentid ?), but since you have a column parent_commandid you most likely do have such a column to reference your comments. Use that to store the comments, on top level or inside other comments.
To sort by internal fields of an array I usually use usort. Usort works as a recursive method so you can ensure that everytime you try to sort an element inside an array you will call your custom function. In this way you will get a more clean code.
Here is an example:
function cmp_rand_score($a, $b)
{
if($a["rand_score"] == $b["rand_score"]){
return 0;
}
return ($a["rand_score"] < $b["rand_score"]) ? 1 : -1;
}
//If you are inside a class:
usort($rows, array($this, "cmp_rand_score"));
//If not you can call directly:
usort($rows, "cmp_rand_score");
Hope it helps.

PHP - Is there a way to verify all values in an array

Using PHP..
Here is what I have.. I'm gonna explain the whole thing and maybe someone can help me with the logic and maybe point me in the right direction.
I have a mail system I am working on. In the cc part, I am allowing the user to seperate the values by a semicolon, like so: 1;2;3;4...
When these values are passed to my function, I am using explode to get them into an array. What I want to do is some checking first. I want to firstly make certain that the format is correct and that every value is correctly seperated. If not, I should show an error. Once this is done, I want to make certain that every number is actually valid. I can query the database, put the reslts into an array and was thinking to use the in_array() function to verify this but I'm not certain that it will work. Can someone please help me out with the best way to handle this?
Thanks.
EDIT:
What is the best way to detect a bogus value in the CSV list of values?
In order to verify that each number was correct seperated, you want to check that there is no whitespace in the answer. So something like this should work:
$text = trim($id);
if(strpos(" ", $id) !== false)
{
//error
}
Next, to check for the values, it is very simple
if(!in_array($id, $database_ids))
{
// error
}
Finally, if you are only using numeric values, check that the id is numeric
if(!is_numeric($id))
{
//error
}
To combine, wrap it into an array
foreach($exploded_array as $key => $id)
{
$id = trim(id);
if(!is_numeric($id))
{
//error
}
if(strpos(" ", $id) !== false)
{
//error
}
if(!in_array($id, $database_ids))
{
// error
}
}
I hope the code was pretty self explanatory where it got the variables, but if you need me to explain more, feel free to ask.
You are looking for something like:
foreach ($array as $value) {
//do checking here
}
array_filter could be an option.
As whichdan suggested, here is an implementation that relies on array_filter():
<?php
function checkValue($value)
{
$id = trim(id);
if(!is_numeric($id))
{
return false;
}
if(strpos(" ", $id) !== false)
{
return false;
}
if(!in_array($id, $database_ids))
{
return false;
}
return true;
}
$values = '1;2;3;4';
$values_extracted = explode(';', $values);
if(count($values) == count(array_filter($values_extracted), 'checkValue'))
{
// Input was successfully validated
}
?>

Categories