bind param count first argument - php

I have the following line:
$formatsArray = $_POST['formats'];
$topicsArray = $_POST['topics'];
// Converting the array into individual strings
$formats = implode(",", $formatsArray);
$topics = implode(",", $topicsArray);
// Prepare the statement
$resources = $con->prepare("SELECT * FROM resources WHERE
(format IN (?))
AND (topic IN (?))");
// Bind the statement
$resources->bind_param('ss',$formats, $topics);
The problem is that topics derived from an array where it could contain multiple string, but 's' will only recognize 1. I would want that if the topic array has 10 entries, than there would be 10s, and same for format.
I have thinking of counting the size of the array and adding an s in every iteration, but not sure how.
Any help would be appreciated.
// Count array
$formatCount = count($formatsArray);
$topicCount = count($topicsArray);

How about this then:
<?php
$con = new mysqli("localhost", "USERNAME", "PASSWORD", "DATABASE");
$formatsArray = array('a','b','c','d',);
$topicsArray = array('x','y','z',);
$sql = 'SELECT * FROM resources WHERE (format IN (FORMAT_REPLACE_ME)) AND (topic IN (TOPIC_REPLACE_ME))';
$formatsPlaceholders = makePlaceHolders($formatsArray);
$topicsPlaceholders = makePlaceHolders($topicsArray);
$sql = str_replace('FORMAT_REPLACE_ME', $formatsPlaceholders, $sql);
$sql = str_replace('TOPIC_REPLACE_ME', $topicsPlaceholders, $sql);
//error_log(print_r($sql,1).' '.__FILE__.' '.__LINE__,0);
try {
$s = $con->prepare($sql);
$vals = array_merge($formatsArray, $topicsArray);
// from http://stackoverflow.com/a/31562035/1814739
$typDfs = str_repeat( 's' , count( $vals ) );
$params = array( $typDfs );
foreach ( $vals as $k => $v ) {
${ 'varvar' . $k } = $v;
$params[] = &${ 'varvar' . $k }; # provide references
}
call_user_func_array( array( $s, 'bind_param' ) , $params );
$s->execute();
$output = array();
$res = $s->get_result();
while ($row = $res->fetch_array(MYSQLI_NUM))
{
//error_log(print_r($row,1).' '.__FILE__.' '.__LINE__,0);
$output []= array(
'id' => $row[0],
'format' => $row[1],
'topic' => $row[2],
);
}
$s->close();
sanitize_output($output);
}
catch (\Exception $e) {
error_log(print_r($e->getMessage(),1).' '.__FILE__.' '.__LINE__,0);
}
function makePlaceHolders($arr){
$ph = '';
for ($i = 1; $i <= count($arr); $i++) {
$ph .= '?,';
}
return rtrim($ph,',');
}
function sanitize_output(array &$arr, array $args=array()) {
array_walk_recursive($arr,'so',$args);
}
function so(&$v,$k,$args) {
$excludes = isset($args['excludes']) ? $args['excludes'] : array();
if (!in_array($k,$excludes)) {
$v = trim($v);
$v = (get_magic_quotes_gpc()) ? stripcslashes($v) : $v;
$v = htmlspecialchars($v);
}
}
?>
<html>
<body>
<ul>
<?php foreach($output as $k => $o) { ?>
<li><?php echo $o['id']; echo $o['format']; echo $o['topic']; ?></li>
<?php } ?>
</ul>
</body>
</html>

Related

Pushing key value pairs into an array from an SQL query

I'm pulling data from a database, and would like to insert it into an array. I would like the array to look like
$myArray = array(
$id => array(
"title" => $title,
"description" => $description,
"tag" => $tag,
"link" => $link
)
)
Where $id is the ID pulled from the database, $title is pulled from the "title" column of the database, and so on.
I need all of this data to be connected so that I can use a template to display the information easily.
Currently this is my code:
<?php
$query = mysqli_query($db_conn, $advice);
//Arrays for the key value pairs
$pregnancyArray = array();
$postpartumArray = array();
$babyArray = array();
$toddlerArray = array();
$parentingArray = array();
//Arrays for now
$pregnancyTitleArray = array();
$pregnancyLinkArray = array();
$pregnancyDescriptionArray=array();
$pregnancyTagArray=array();
$postpartumTitleArray = array();
$postpartumLinkArray = array();
$babyTitleArray = array();
$babyLinkArray = array();
$toddlerTitleArray = array();
$toddlerLinkArray = array();
$parentingTitleArray = array();
$parentingLinkArray = array();
function createSlug($slug)
{
$LNSH = '/[^\-\s\pN\pL]+/u';
$SDH = '/[\-\s]+/';
$slug = preg_replace($LNSH, '', mb_strtolower($slug, 'UTF-8'));
$slug = preg_replace($SDH, '-', $slug);
$slug = trim($slug, '-');
return $slug;
}
while ($row = mysqli_fetch_array($query)) {
$id = $row['adviceID'];
$title = $row['title'];
$cat = $row['cat'];
$link = createSlug($title);
$description = $row['description'];
$tag = $row['tag'];
if ($cat === 'pregnancy') {
array_push($pregnancyTitleArray, $title);
array_push($pregnancyLinkArray,$link);
array_push($pregnancyDescriptionArray, $description);
if($tag){
array_push($pregnancyTagArray, $tag);
}
else {
array_push($pregnancyTagArray, "nt");
}
} elseif ($cat === 'postpartum') {
array_push($postpartumTitleArray, $title);
array_push($postpartumLinkArray,$link);
} elseif ($cat === 'baby') {
array_push($babyTitleArray, $title);
array_push($babyLinkArray,$link);
} elseif ($cat === 'toddler') {
array_push($toddlerTitleArray, $title);
array_push($toddlerLinkArray,$link);
} elseif ($cat === 'parenting') {
array_push($parentingTitleArray, $title);
array_push($parentingLinkArray,$link);
} else {
continue;
}
}
?>
<section class="content" id="pregnancy-advice">
<h2 class="heading">Pregnancy Advice</h2>
<ul class="justified-content" style="list-style-type: none;">
<?php
for($i = 0; $i < sizeof($pregnancyTitleArray) && $i <= 15; $i++){
echo "<li class=\"extra-spacing\">" . $pregnancyTitleArray[$i] . "</li>";
}
?>
<a class="more-links" href="adviceCat.php?cat=pregnancy">More -></a>
</ul>
</section>
Can you just build an array with your result set like so:
$results = [];
while ($row = mysqli_fetch_array($query)) {
$results[$row['adviceID']] = $row;
$results[$row['adviceID']]['link'] = createSlug($title);
}
If you'd only like to have certain data in your array you can build it differently:
$results = [];
while ($row = mysqli_fetch_array($query)) {
$results[$row['adviceID']] = array(
'title' => $row['title'],
'description' => $row['description'],
'tag' => $row['tag'],
'link' => createSlug($title),
);
}

How to get all the results where parent is an item from an array

I have an array that consists names of parents ,I want to get all the results where any of the name is a parent.Here is my code.I am not able to get the list of names where parent is equal to the names in district array.
Here is my complete code.
<?php
$functionname = 'core_course_get_categories';
$username = array('key' => 'name', 'value' => '2016');
$params = array('criteria' => array($username));
$server_url = 'localhost/moodle' . '/webservice/rest/server.php' . '?wstoken=' . '9cdaccf3a7ad2f0f94922ccfd02559f4' . '&wsfunction=' . $functionname;
$rest_format = 'json';
require_once('curl.inc');
$curl = new curl;
$rest_format = ($rest_format == 'json') ? '&moodlewsrestformat=' . $rest_format : '';
$resp = $curl->post($server_url . $rest_format, $params);
$res = json_decode($resp);
// drupal_set_message('<pre>'. dpm($res) .'</pre>');
$district = array();
$Ctsc = array();
$School = array();
$Grade = array();
$parent = array();
foreach ($res as $r) {
$a = $r->parent;
$c = $r->name;
if ($a == 0) {
$b = $r->id;
var_export($b);
}
}
foreach ($res as $r) {
if ($r->parent == $b) {
//$dist=$r->name;
$district[] = $r->name;
}
}
$Ctsc[] = $r->description;
$School[] = $r->sortorder;
$Grade[] = $r->depth;
foreach ($res as $r) {
$q = $r->name;
if (in_array($q['parent'], $district)) {
$Ctsc[] = $q->name;
dpm($Ctsc);
}
if ($Ctsc['parent'] == $district) {
dpm($Ctsc);
}
}
Usage of in_array() is wrong.
Instead of
if(in_array($q['parent'] == $district)){ ... }
use
if(in_array($q['parent'], $district)){ ... }

How to add a value at the end of JSON

$resultado = mysqli_query("SELECT ...");
echo '[';
for ($i=0;$i<mysqli_num_rows($resultado);$i++) {
echo ($i > 0 ? ',' : '').json_encode(mysqli_fetch_object($resultado));
}
echo ']';
Need is Insert $SLUG the end of Json so it is the same object
{
tabela:valor
slug:valor
}
tried to array_push() but without success;
You have to encode final result, not each row:
$array = array();
for ($i=0;$i<mysqli_num_rows($resultado);$i++) {
$array[] = mysqli_fetch_object( $resultado );
}
$array[] = $SLUG; # <----------------
echo json_encode( $array );
Different approach:
$array = array();
for ($i=0;$i<mysqli_num_rows($resultado);$i++) {
$array[] = mysqli_fetch_object( $resultado );
}
$final = array( 'tabela' => $array(), 'slug' => $SLUG );
echo json_encode( $final );

Executing pre-build-up array with PDO Execute

I am trying to pass through any query to a function using PDO.
I have build up the array through a loop function and try to insert it into the execute(array(....)) function, but it's not getting through.
FUNCTION CODE
public function ShowData($sql,$variable)
{
$execute_string = "";
echo "<pre>";
print_r($variable);
echo "</pre>";
$q = $this->conn->prepare($sql);
for($i = 0; $i < sizeof($variable); $i++)
{
if($i != 0) $execute_string .= ",";
$placeholder = $i + 1;
$execute_string .= "':$placeholder' => '".$variable[$i]."'";
}
echo $sql."<br>";
echo $execute_string;
$q->execute(array($execute_string));
echo "<br>Execute Succeeded";
return $row = $q->fetchAll();
}
VIEWPAGE CODE
$author = "Nemoza";
$name = "MBICO_mailer";
$project = $data->ShowData("SELECT * FROM mbico_projects WHERE author=:1 AND name=:2", array($author,$name));
OUTPUT FROM FUNCTION W/ DEBUGGING
Array
(
[0] => Nemoza
[1] => MBICO_mailer
)
SELECT * FROM mbico_projects WHERE author=:1 AND name=:2
':1' => 'Nemoza',':2' => 'MBICO_mailer'
However, the 'Execute Succeeded' text is not being printed, and the execute(array...)) is not actually executing.
What am I doing wrong, and how else should I do it?
here's an example you can use:
public function ShowData($sql,$variable) {
$bind = [];
foreach ($variable as $key => $value) {
$ph = $key+1;
$bind[":" . $ph] = $value;
}
$stmt = $this->conn->prepare($sql);
$stmt->execute($bind);
return $stmt->fetchAll();
}
it's used like this:
$sql = 'select * from users where username = :1 or username = :2';
$bind = ['123', '456'];
$db->ShowData($sql, $bind);
as mentioned in the comments to your question, you need to send an array to execute() function, and not a string.
Managed to do it like this:
public function ShowData($sql,$variable)
{
$execute_string = array();
$q = $this->conn->prepare($sql);
foreach($variable as $item)
{
$execute_string[] = $item;
}
$q->execute($execute_string);
return $q->fetchAll();
}
$project = $data->ShowData("SELECT * FROM mbico_projects WHERE author=? AND title=?", array($author, $title));

Calculate all possible combinations from sets/groups

I need to create a list of urls for all possible combinations from a set of filters/parameters.
Input
$data = array(
array(
'vehicle=car',
'vehicle=bike',
'vehicle=plane',
),
array(
'fruit=apple',
'fruit=banana',
'fruit=strawberry'
),
array(
'music=pop',
'music=rock',
'music=jazz'
)
);
The generated items must have the parameters in alphabetical order.
For example:
INCORRECT: ?vehicle=bike&fruit=apple&music=rock
CORRECT: ?fruit=apple&music=rock&vehicle=bike
Output
?vehicle=car
?vehicle=bike
?vehicle=plane
?fruit=apple&vehicle=car
?fruit=banana&vehicle=car
?fruit=strawberry&vehicle=car
?fruit=apple&vehicle=bike
?fruit=banana&vehicle=bike
?fruit=strawberry&vehicle=bike
?fruit=apple&vehicle=plane
?fruit=banana&vehicle=plane
?fruit=strawberry&vehicle=plane
?fruit=apple&music=pop&vehicle=car
?fruit=apple&music=rock&vehicle=car
?fruit=apple&music=jazz&vehicle=car
?fruit=banana&music=pop&vehicle=car
?fruit=banana&music=rock&vehicle=car
?fruit=banana&music=jazz&vehicle=car
?fruit=strawberry&music=pop&vehicle=car
?fruit=strawberry&music=rock&vehicle=car
?fruit=strawberry&music=jazz&vehicle=car
?fruit=apple&music=pop&vehicle=bike
?fruit=apple&music=rock&vehicle=bike
?fruit=apple&music=jazz&vehicle=bike
?fruit=banana&music=pop&vehicle=bike
?fruit=banana&music=rock&vehicle=bike
?fruit=banana&music=jazz&vehicle=bike
?fruit=strawberry&music=pop&vehicle=bike
?fruit=strawberry&music=rock&vehicle=bike
?fruit=strawberry&music=jazz&vehicle=bike
?fruit=apple&music=pop&vehicle=plane
?fruit=apple&music=rock&vehicle=plane
?fruit=apple&music=jazz&vehicle=plane
?fruit=banana&music=pop&vehicle=plane
?fruit=banana&music=rock&vehicle=plane
?fruit=banana&music=jazz&vehicle=plane
?fruit=strawberry&music=pop&vehicle=plane
?fruit=strawberry&music=rock&vehicle=plane
?fruit=strawberry&music=jazz&vehicle=plane
?music=pop&vehicle=car
?music=rock&vehicle=car
?music=jazz&vehicle=car
?music=pop&vehicle=bike
?music=rock&vehicle=bike
?music=jazz&vehicle=bike
?music=pop&vehicle=plane
?music=rock&vehicle=plane
?music=jazz&vehicle=plane
?fruit=apple
?fruit=banana
?fruit=strawberry
?fruit=apple&music=pop
?fruit=apple&music=rock
?fruit=apple&music=jazz
?fruit=banana&music=pop
?fruit=banana&music=rock
?fruit=banana&music=jazz
?fruit=strawberry&music=pop
?fruit=strawberry&music=rock
?fruit=strawberry&music=jazz
?music=pop
?music=rock
?music=jazz
Is there anyone that could help me out with this. I've been struggling with it for two days now but I can't seem so find a correct solution. There are a lot of (almost) similar issues on Stackoverflow but none of them seems to solve/fit my problem.
[SOLVED]
Here is the final working version based on Dusan Plavak's answer:
function createFilterCombinations($data, &$urls = array(), $index = 0, $query = false){
$keys = array_keys($data);
$_query = $query;
if ($index == count($data)) {
return;
}
for($i=0; $i < count($data[$keys[$index]]); $i++){
$query = $_query;
if($index == 0){
$query = "?" . $data[$keys[$index]][$i];
}else{
if($query != "?"){
$query .= "&" . $data[$keys[$index]][$i];
}else{
$query .= $data[$keys[$index]][$i];
}
}
$urls[] = $query;
createFilterCombinations($data, $urls, $index+1, $query);
}
if($index == 0){
$query = "?";
} else {
$query = $_query;
}
createFilterCombinations($data, $urls, $index+1, $query);
}
function prepareArray($array){
$newArray = array();
foreach ($array as $subArray) {
sort($subArray);
$newArray[substr($subArray[0], 0, strpos($subArray[0], '='))] = $subArray;
}
ksort($newArray);
return $newArray;
}
createFilterCombinations(prepareArray($data), $result);
var_dump($result);
So look at this http://codepad.org/TZWf7Vxd
and code for a time when link will be dead :D
<?php
$data = array(
"vehicle" => array(
'vehicle=car',
'vehicle=bike',
'vehicle=plane',
),
"fruit" => array(
'fruit=apple',
'fruit=banana',
'fruit=strawberry'
),
"music" => array(
'music=pop',
'music=rock',
'music=jazz'
)
);
function hop($index, $query, $data){
$keys = array_keys($data);
if($index == count($data)){
return;
}
$queryBackup = $query;
for($i=0;$i<count($data[$keys[$index]]);$i++){
$query = $queryBackup;
if($index == 0){
$query = "?".$data[$keys[$index]][$i];
}else{
if($query != "?"){
$query .= "&".$data[$keys[$index]][$i];
}else{
$query .= $data[$keys[$index]][$i];
}
}
echo $query."\n";
hop($index+1, $query, $data);
}
if($index == 0){
$query = "?";
}else{
$query = $queryBackup;
}
hop($index+1, $query, $data);
}
ksort($data);
hop(0,"", $data);
?>
This is not a ready-made solution but you can use a function that returns an array combinations. I hope this could help You.
<?
$collect = false;
function combinations($arr, $temp_string, &$collect) {
if ($temp_string != "")
$collect[] = $temp_string;
for ($i = 0; $i < sizeof($arr); $i++) {
$arrcopy = $arr;
$elem = array_splice($arrcopy, $i, 1);
if (sizeof($arrcopy) > 0) {
combinations($arrcopy, $temp_string . " " . $elem[0], $collect);
} else {
$collect[] = $temp_string . " " . $elem[0];
}
}
return $collect;
}
var_dump(combinations(array('abc', 'cde', 'fgi'),'',$collect));
?>
see WORKING CODE

Categories