Avatar billede Morten Professor
04. april 2021 - 18:54 Der er 21 kommentarer og
1 løsning

Array_unique values i en mysqli fetch_array? Har prøvet distinct

Hej håber der er nogle der kan hjælpe mig med at lave en filtering af mine values. Så den ikke duplicate da jeg en masse varianter med samme sku. Men har kun for at output values fra row en for hver sku har prøvet distinct i sql
Og Array_unique i en del af while loop

Og et andet spørgsmål hvordan laver man et limit loop hvor den bliver ved med at loop feks 1000 row af gangen se kode på https://www.computerworld.dk/eksperten/spm/1036845?k=8377613
Jeg laver det for at loop igennem til en XML.

Jeg har desværre ikke forstået hvordan man gør det så den bliver ved indtil den er færdig. Men ikke bare en enkelt gang som har en limit på 1000.

Med venlig hilsen
Morten
Avatar billede olsensweb.dk Ekspert
04. april 2021 - 19:34 #1
>Og et andet spørgsmål hvordan laver man et limit loop hvor den bliver ved med at loop feks 1000 row af gangen se kode på
prøv at goole Pagination
https://www.google.com/search?q=php+Pagination
https://www.google.com/search?q=php+Paging
Avatar billede Morten Professor
04. april 2021 - 19:50 #2
Hej

Har prøvet det men tænker ikke lige var på den måde, da jeg så skal trykke hver gang på næste før den så tager næste row.
Eller er der bare ikke andre muligheder, hvor den bare køre nogle frekvenser selv?
Avatar billede olsensweb.dk Ekspert
04. april 2021 - 22:03 #3
prøv at lege lidt med denne.

de henter data fra databasen i klumper af 5 records, og ligger det over i det store dataarray
<?php
function users_total_records($conn){
    $total_antal=0;
    $sql = "SELECT count(id) as antal FROM tbl_users";
    $rs = $conn->query($sql);
    if($rs){
        $row = $rs->fetch_assoc();       
        $total_antal =  $row['antal'];
    }   
    return $total_antal;
}

function users_Read_All_Limit($conn, $numbers, $offset){
    $data=array();
    $sql = "SELECT * FROM tbl_users LIMIT ".$offset.",".$numbers;
    $rs = $conn->query($sql);
    while($obj = $rs->fetch_object() ){       
        $data[]= $obj;
    }   
    return $data;
}

////////////////////////////////////////////////////////
$mysqli = new mysqli ( "localhost", "root", "", "test" );
if (! $mysqli) {
    echo 'Der opstod en fejl.';
    exit ();
}
$mysqli->set_charset( "utf8" );


// faste værdier
$antal_pr_side = 5;   
$total_antal = users_total_records($mysqli);
$offset = 0;
$total_read = 0;
$data=array();


// henter fra databasen i små klumper, uden brugeren skal gøre noget
while($offset<$total_antal){
$tmp = users_Read_All_Limit($mysqli, $antal_pr_side, $offset);
print_r($tmp); // test

// løber det midlertidige array igennem, og ligger det i det store array
// and ($total_read<$total_antal) => sikre jeg ikke løber for langt i mit array,
for($i=0; ($i<$antal_pr_side) and ($total_read<$total_antal);$i++){
        $data[] = $tmp[$i];   
        $total_read++;   
}
$offset +=$antal_pr_side;
}





// kontrol
echo "<pre>";
print_r($data);
echo "</pre>";
?>
Avatar billede olsensweb.dk Ekspert
05. april 2021 - 05:24 #4
ryddet lidt op i coden
while løkke uden for functionen er lavet om
<?php
function users_Read_All_Limit($conn, $numbers, $offset) {
    $data = array();
    $sql = "SELECT * FROM tbl_users LIMIT " . $offset . "," . $numbers;
    $rs = $conn->query($sql);
    while ($obj = $rs->fetch_object()) {
        $data[] = $obj;
    }
    return $data;
}

////////////////////////////////////////////////////////
$mysqli = new mysqli("localhost", "root", "", "test");
if (!$mysqli) {
    echo 'Der opstod en fejl.';
    exit();
}
$mysqli->set_charset("utf8");


// faste værdier
$antal_pr_side = 5; // denne værdi skal ændres
$offset = 0;
$data = array();

// henter fra databasen i små klumper, uden brugeren skal gøre noget
$run = true;
while ($run) {
    $tmp = users_Read_All_Limit($mysqli, $antal_pr_side, $offset);
    $lng = count($tmp);
    if ($lng == 0) {
        $run = false;
        break;
    }
// løber det midlertidige array igennem, og ligger det i det store array
    for ($i = 0; $i < $lng; $i++) {
        $data[] = $tmp[$i];
    }
    $offset += $antal_pr_side;
}

echo "<pre>";
print_r($data);
echo "</pre>";
?>
Avatar billede Morten Professor
05. april 2021 - 12:53 #5
Hej

Er i fuld gang med at koble det sammen.
Skal bare lige ud af hvordan prøver mig frem og ser om der sker noget snart :D
Avatar billede Morten Professor
05. april 2021 - 12:56 #6
Ser dette rigtig ud

function users_Read_All_Limit($con, $numbers, $offset) {
    global $wpdb;
    $con = $wpdb->__get('dbh');
    $data = array();
    $sql = "
SELECT DISTINCT ID, post_date, **_posts.guid, **_posts.post_modified, **_posts.post_parent, **_posts.post_title, **_posts.post_type, **_postmeta.post_id, **_postmeta.meta_value, **_postmeta.meta_key
    FROM **_posts INNER JOIN **_postmeta ON ID = **_postmeta.post_id WHERE post_type in ('product', 'product_variation', 'attachment') and **_postmeta.meta_key in ('_stock', '_sku', '_regular_price', '_sale_price', '_wp_attached_file') ORDER BY **_postmeta.post_id, **_postmeta.meta_id ASC LIMIT ".$offset.",".$numbers;
    $rs = $con->query($sql);
    while ($obj = $rs->fetch_object()) {
        $data[] = $obj;
    }
    return $data;
}
Avatar billede olsensweb.dk Ekspert
05. april 2021 - 16:18 #7
hvorfor anvender du global ??, det er dårlig kodeskik
hvorfor har du $con med over som parameter ?? du oversriver den alligevel.
jeg ville tage wpdb over som parameter istedet for $con

forudsat du har adgang til $wpdb og din sql virker, burde coden se sådan ud

(utested har ikke WP installeret, og aldrig lavet noget til WP)
<?php
// https://www.computerworld.dk/eksperten/spm/1036845?k=8377558
// https://www.computerworld.dk/eksperten/spm/1036845?k=8377610
// https://www.computerworld.dk/eksperten/spm/1036845?k=8377564
function users_Read_All_Limit($wpdb, $numbers, $offset) {
    $con = $wpdb->__get('dbh');
    $data = array();
    $sql = "SELECT DISTINCT ID, post_date, **_posts.guid, **_posts.post_modified, **_posts.post_parent, **_posts.post_title, **_posts.post_type, **_postmeta.post_id, **_postmeta.meta_value, **_postmeta.meta_key FROM **_posts INNER JOIN **_postmeta ON ID = **_postmeta.post_id WHERE post_type in ('product', 'product_variation', 'attachment') and **_postmeta.meta_key in ('_stock', '_sku', '_regular_price', '_sale_price', '_wp_attached_file') ORDER BY **_postmeta.post_id, **_postmeta.meta_id ASC LIMIT ".$offset.",".$numbers;
    $rs = $con->query($sql);
    while ($row = $rs->fetch_array(MYSQLI_ASSOC) ) {
        $data[] = $row;
    }
    return $data;
}


// faste værdier
$antal_pr_side = 5; // denne værdi skal ændres
$offset = 0;
$data = array();

// henter fra databasen i små klumper, uden brugeren skal gøre noget
$run = true;
while ($run) {
    $tmp = users_Read_All_Limit($wpdb, $antal_pr_side, $offset);
    $lng = count($tmp);
    if ($lng < $antal_pr_side) {
        $run = false;       
    }
    if ($lng == 0) {       
        break;
    }
// løber det midlertidige array igennem, og ligger det i det store array
    for ($i = 0; $i < $lng; $i++) {
        $data[] = $tmp[$i];
    }
    $offset += $antal_pr_side;
}


// https://www.computerworld.dk/eksperten/spm/1036845?k=8377436
// skal her gennem med XmlWriter

// test / kontrol
echo "<pre>";
print_r($data);
echo "</pre>";
?>

ellers må du skrive hvilke fejl du får
Avatar billede Morten Professor
06. april 2021 - 09:30 #8
Hej

Har prøvet noget tid men kan ikke finde fejlen
Den siger Fatal error: Uncaught ArgumentCountError: Too few arguments to function users_Read_All_Limit(), 1 passed

Den ser ellers sådan ud function users_Read_All_Limit($wpdb, $numbers, $offset) {
Avatar billede olsensweb.dk Ekspert
06. april 2021 - 09:32 #9
du kunne overveje at kigge på call by ref så du ikke skal retunerer et stort array, fra functionen
<?php
require_once("connection.php"); // $mysqli
// https://www.php.net/manual/en/language.references.pass.php
// ved call by ref skal referancen i functionen have et andet navn end det globale, da man eller kun får den sidste klump
function users_Read_All_Limit($conn, &$data_ref, $numbers, $offset) {
    $data = array();
    $sql = "SELECT * FROM tbl_users LIMIT " . $offset . "," . $numbers;
    $rs = $conn->query($sql);
    $row_cnt = $rs->num_rows;
    while ($row = $rs->fetch_array(MYSQLI_ASSOC)) {
        $data_ref[] = $row;
    }
    return $row_cnt;
}

////////////////////////////////////////////////////////
// faste værdier
$antal_pr_side = 5; // denne værdi skal ændres
$offset = 0;
$data = array();

// henter fra databasen i små klumper, uden brugeren skal gøre noget
$run = true;
while ($run) {
    $lng = users_Read_All_Limit($mysqli, $data, $antal_pr_side, $offset);
    if ($lng < $antal_pr_side) {
        $run = false;
    }
    if ($lng == 0) {
        break;
    }
    $offset += $antal_pr_side;
}

echo "<pre>";
print_r($data);
echo "</pre>";
?>



endelig kan du droppe functionen helt, og ligge det hele i while løkken, hvis du synes det er kønnere
<?php
require_once("connection.php"); // $mysqli
// faste værdier
$antal_pr_side = 5; // denne værdi skal ændres
$offset = 0;
$data = array();

$run = true;
while ($run) {   
    $sql = "SELECT * FROM tbl_users LIMIT " . $offset . "," . $antal_pr_side;
    $rs = $mysqli->query($sql);
    $lng = $rs->num_rows;
    while ($row = $rs->fetch_array(MYSQLI_ASSOC)) {
        $data[] = $row;
    }   
    if ($lng < $antal_pr_side) {
        $run = false;
    }
    if ($lng == 0) {
        break;
    }
    $offset += $antal_pr_side;
}

echo "<pre>";
print_r($data);
echo "</pre>";
?>
Avatar billede olsensweb.dk Ekspert
06. april 2021 - 09:55 #10
#8
>Den ser ellers sådan ud function users_Read_All_Limit($wpdb, $numbers, $offset) {
hvordan ser dit kald ud ??
bør være
$tmp = users_Read_All_Limit($wpdb, $antal_pr_side, $offset);


#9
>// ved call by ref skal referancen i functionen have et andet navn end det globale, da man eller kun får den sidste klump
man kunne selvføgelig bare slette  $data = array(); inde i functionen :)
Avatar billede Morten Professor
06. april 2021 - 10:17 #11
Jeg prøvede lige uden function delen og lage den ind sammen med det andet får noget ud nu.

Men det stopper bare ved når den når 5 eller 10 hvad jeg lige vælger:
Det ser sådan ud nu før jeg kunne få den igang:
$con = $wpdb->__get('dbh');
        $rs = $con->query($sql);
        $lng = $sql->num_rows;
        while ($row = $rs->fetch_array(MYSQLI_ASSOC)) {
            $data[] = $row;
        }
        if ($lng < $antal_pr_side) {
            $run = false;
        }
        if ($lng == 0) {
            break;
        }
        $offset += $antal_pr_side;
    }

    echo "<pre>";
    print_r($data);
    echo "</pre>";
Avatar billede Morten Professor
06. april 2021 - 10:19 #12
Hvis jeg gør sådan står den stille

$con = $wpdb->__get('dbh');
        $rs = $con->query($sql);
        $lng = $rs->num_rows;
        while ($row = $rs->fetch_array(MYSQLI_ASSOC)) {
            $data[] = $row;
        }
        if ($lng < $antal_pr_side) {
            $run = false;
        }
        if ($lng == 0) {
            break;
        }
        $offset += $antal_pr_side;
    }

    echo "<pre>";
    print_r($data);
    echo "</pre>";

Jeg beklager jeg er en grønskolling :o)
Avatar billede Morten Professor
06. april 2021 - 11:09 #13
Nu bliver der oprettet xml records
Men der er ikke noget i dem sådan som koden ser ud:
while ($row = $rs->fetch_array(MYSQLI_ASSOC)) {
            $data[] = $row;
        }

while($key = $data) {
    $post_title = $key['post_title'];
    $post_modified = $key['post_modified'];
    $guid = get_permalink($key['ID']);
Avatar billede Morten Professor
06. april 2021 - 11:35 #14
Den løber ligeså fint igennem nu men der kommer bare ingen data ind i xml
while ($row = $rs->fetch_array(MYSQLI_ASSOC)) {
            $data[] = $row;

    $post_title = $data['post_title'];
    $post_modified = $data['post_modified'];
    $guid = get_permalink($data['ID']);

Sådan prøver jeg nu. Men der kommer bare ikke data ind kun uden values
Ser sådan ud
<item ExternalId="" Modified="" Name="" ImageLink="" AdditionalImageLink="" Link="" Gender="" Brand="" InStock="" ItemGroupId="" RegularPrice="" SalePrice=""/>
Avatar billede Morten Professor
06. april 2021 - 11:38 #15
Hvis jeg gør sådan med statisk tekst virker det fint
$xml->writeAttribute('ExternalId', "HEJ");
Avatar billede Morten Professor
06. april 2021 - 11:59 #16
SÅ LYKKEDES DET :)
Avatar billede Morten Professor
06. april 2021 - 13:26 #17
Har nogle problemer med duplicated content har prøvet med DISTINCT og group by Men det virker ikke.
Har du nogle ideer?
Avatar billede Morten Professor
07. april 2021 - 06:32 #18
Hej

1000 tak for hjælpen. Så kom jeg i mål.
Jeg opretter lige en ny med hvordan man får fjernet duplicated content.
For selv om jeg har bruget Group by og distinct vil det stadig ikke virke.
Avatar billede olsensweb.dk Ekspert
07. april 2021 - 06:49 #19
#18
for at DISTINCT  skal virke skal alle seleterede data være ens, hvis bare en kollonne er forskællig, vil ræken være forskællig, og du har altid en kollonne der er forskællig (ID, er autonummereret)
Avatar billede Morten Professor
07. april 2021 - 07:33 #20
Hvad kan man gøre er der en workaround på det. eller er der bare ikke noget at gøre?
Avatar billede olsensweb.dk Ekspert
07. april 2021 - 08:06 #21
#20
lad være med at selectere felter der er autonummereret typisk ID, de vil altid være unik, og dermed kan rækkerne ikke blive ens

SELECT DISTINCT ID,



btw:
har **_postmeta ikke en id (primær nøgle) ??, det vil give en fejl, fordi den ikke kan finde ud af hvilke id du ønsker.
jeg forvendter der er en
**_posts.id
**_postmeta.id

men kender ikke strudturen på dine tabeller.
når du i en sql laver join, bør du altid angive tabel navnet på dine felter evt med alias

https://www.w3schools.com/sql/sql_alias.asp
Avatar billede Morten Professor
07. april 2021 - 08:23 #22
auto meta_id i postmeta tabelen
post_id i postmeta, Post_id er den samme fra Auto ID

Håber det kan give en ide om hvordan det hænger sammen
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester