• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Plik JSON - weryfikacja + zapis do bazy

Object Storage Arubacloud
0 głosów
2,984 wizyt
pytanie zadane 12 maja 2015 w PHP przez Silesianek Nowicjusz (200 p.)

Witam,
Od pewnego czasu wolne chwile poświęcam na nauke php + mysql. Kilka dni temu wymyśliłem sobie zadanie, które chyba przekracza poziom mojej wiedzy, a jak to czasem bywa - cieżko odpuścić dobry pomysł, mimo braku umiejętności. Pomyślałem, że może tutaj dostanę jakieś wskazówki które pomogą mi zrealizować mój projekt. Postaram się wyjaśnić cały zamysł od początku do końca.


Otrzymuje z jednego z serwisów internetowych plik (api) w formacie json, który zawiera potrzebne mi informacje o użytkownikach. Plik ten aktualizuje się co kilka minut, a zadaniem naszego "programu" jest weryfikowanie czy informacje które tam się znajdują pokrywają się z bazą danych którą stworzyłem na podstawie tego pliku.
Plik json ma taki format:

{
request: {klucz: "wartość"
},
dane: [
{
SERWIS_ID: "wartość",
SERWIS_NAME: "wartość",
LOGO: "wartość",
LOGO_SMALL: "wartość",
DATA: "wartość",
NOTIF: "wartość",
},
{
SERWIS_ID: "wartość",
SERWIS_NAME: "wartość",
LOGO: "wartość",
LOGO_SMALL: "wartość",
DATA: "wartość",
NOTIF: "wartość",
},
],
max_results: "wartość"
}

Wszystkie pozycje w tablicy "dane" posiadają zawsze te same klucze, różnią się tylko wartości. Tylko te dane biorę pod uwagę (max_results oraz request nie są mi na tą chwilę potrzebne). Zadaniem naszego pliku php jest monitorowanie czy nastąpiły zmiany w pliku json oraz korygowanie danych w bazie danych.

Mam bazę danych która zawiera tablę zawierającą wszystkie klucze z tablicy dane. Wygląda w taki sposób:
1    ID                          int(11)                                AUTO_INCREMENT    
2    SERWIS_ID            int(11)    
3    SERWIS_NAME    text            utf8_polish_ci    
4    LOGO                    text            utf8_polish_ci    
5    LOGO_SMALL        text            utf8_polish_ci    
6    DATA                    datetime    
7    NOTIF                    int(11)    
8    ACTIVE                int(11)

Jak widać ID zapisuje się samo, kolejne kolumny pokrywają się z kluczami pliku JSON w tablicy dane, a na samym końcu jest kolumna ACTIVE, która ma odpowiadać za "oflagowanie" czy dany użytkownik ciągle znajduję się w pliku JSON.
Plik php który do tej pory udało mi się stworzyć wygląda następująco: 

<?php
	require_once "connect.php";
	error_reporting(E_ALL);
	ini_set('display_errors', 1);
// Tworzenie połączenia
	$conn = new mysqli($host, $db_user, $db_password, $db_name);
// Sprawdzenie połączenia
	if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
	} 
	$url = "https://adres pliku json";
	$json = json_decode(file_get_contents($url), true);
	for($i=0; $i<count($json['dane']); $i++)
{
    $sql = array();
    foreach($json['dane'][$i] as $key => $value){
		if ($key == 'SERWIS_ID') 
		{
Tutaj brak kodu
		}
    }  
}
?>

Chciałbym sprawdzić czy każdy użytkownik w pliku znajduje się się w bazie danych. Jeśli nie to chciałbym dodać go do bazy ze wszystkimi wartościami, a jeśli tak to sprawdzić czy pozostałe wartości pokrywają się z bazą danych (jeśli nie to zauktualizować). Dodatkowo chciałbym sprawdzić czy znajdują się w bazie danych tacy użytkownicy których nie ma już w pliku json i zmienić wartość kolumny ACTIVE z 1 na 0 (domyślnie zapisuje się jako 1).

Pomożecie?

Pozdrawiam,
Mateusz

1 odpowiedź

+3 głosów
odpowiedź 13 maja 2015 przez efiku Szeryf (75,160 p.)
1. Przejdź na jasną stronę mocy z biblioteką PDO: http://pl.wikibooks.org/wiki/PHP/Biblioteka_PDO

2. Gotowca raczej nie będzie ale:

Zadanie ciekawe, wystarczy dodać zadanie do crona by odpalał plik php który pobierze dane z tego serwisu co X dni np.

Lepiej jest trzymać cache tego pliku i sprawdzać sumy md5 jeśli się zgadzają, to znaczy, że ten plik nie został zmieniony. I przerywać prace pliku

Ja bym powiedział, że nie użytkownik tylko serwis, bo się to bardzo myli. Moim zdaniem aby nie mulić bazy requestami możesz operować właśnie na pliku cache, skoro sumy są inne to coś się zmieniło. 1 plik dekodujesz jsonem otrzymujesz piękną tablicę asocjacyjną, potem 2 plik pobieraz od API. Popatrz na operatory tablicowe. Możesz porównywać to co masz w każdym kluczu , jesli 1 tablica !== od drugiej to dodajesz zapytanie do bazy które aktualizuje cały row WHERE SERWIS_ID ;-) [...] to taki zarys na szybko algorytmu, nie jest super optymalny, ale lepsze to niż tysiące zapytań do bazy xd

 

3. Twój kod trochę jest bez sensu. Po co na produkcji włączanie błędów ? Przecież jak pracujesz u siebie na kompie to pracujesz w środowisku dev z domyślnie włączonym wyświetlaniem błędów.
komentarz 13 maja 2015 przez Silesianek Nowicjusz (200 p.)
Witam!

Dziękuję za odpowiedź, plik w większości został stworzony na podstawie kursu php oraz mysql Pana Mirosława, dlatego nie skorzystałem z biblioteki PDO, bo z tego co pamiętam jeszcze jej na kursie nie było. Uwaga trafna dlatego z chęcia poczytam na temat tej metody.

Plik JSON który otrzymuje to lista użytkowników którzy śledzą jeden z profili, jednak w każdej chwili mogą przestać go śledzić - stąd też opcja zachowania ich w bazie jednak z opcja "nieaktywny". Jedyne dane które mogą się zmienić to LOGO oraz LOGO_SMALL, reszta jest zawsze taka sama. Dlatego jedyne co potrzebuje spradzać regularnie to:
1. Czy wszyscy użytkownicy znajdujący się w pliku JSON znajdują się w bazie
       a) TAK - Sprawdz czy nie zmienili LOGO oraz LOGO_SMALL
       b) NIE - Dodaj brakujących oraz sprawdz pozostałych czy nie zmienili LOGO oraz LOGO_SMALL
2. Sprawdz czy w bazie danych są użytkownicy których ID nie ma w pliku JSON
      a) NIE MA TAKICH - nic nie rów
      b) SĄ TACY - Ustaw ich wartość ACTIVE na 0.

Jeśli chodzi o crona to właśnie w ten sposób będzie odpalany ten plik, co kilkanaście minut.
Pomysł z plikiem chache wydaje się ciekawy jednak nie wiem czy moja wiedza jest na tyle duża aby sobie z tym poradzić.
Chyba jednak wolę pomęczyć bazę danych zapytaniami i z czasem polepszyć i zoptymalizować kod.

Pozdrawiam!
komentarz 13 maja 2015 przez efiku Szeryf (75,160 p.)

W takim razie nie sprecyzowałeś dokładnie co się zmienia :P ja bym zmieniał cały rekord bo lepiej. 

http://stackoverflow.com/questions/12048633/sql-query-to-find-record-with-id-not-in-another-table takie zapytanie mozna poslac jak chcesz mulic requesty xd

Nie wiem czy liczysz na to abym za Ciebie to rozwiązał, ale prześledź to co napisałem kilka razy, bo lepiej jest pobrac za pomoca juz tego file get contents to co jest w pliku, dac go jako cache ( jesli plik cache nie istnieje to stworzyć go z tej tresci co pobrales i dodac wszystko do bazy za 1 zamachem) , pozniej plik ktory masz w jakims katalogu np cache porownywac z plikiem pobranym, oba jako json decode i wtedy mozesz szybko sobie popatrzeć jakie rekordy się zmieniły. 

Wybacz, idę teraz na kebaba to nie wiele zdziałam :D

a i jeszcze jedno:

komentarz 13 maja 2015 przez Silesianek Nowicjusz (200 p.)

Witam,

Dziękuję za kolejne wskazówki. Oczywiście nie chcę gotowych rozwiązań a jedynie wskazówki i porady. Po kilku godzinach zabawy mój kod już wygląda zdecydowanie obszerniej :)
Brakuje mi jedynie poprawy funkcji sprawdzenia czy wszystkie dane się zgadzają (linijka 30) oraz sprawdzenia czy są jakieś rekordy w bazie których nie ma w pliku json.

 

<?php
	require_once "connect.php";
// Create connection
	$conn = new mysqli($host, $db_user, $db_password, $db_name);
// Check connection
	if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
	} 
// Get api json file
	$url = "api link";
	$json = json_decode(file_get_contents($url), true);
	
	
	for($i=0; $i<count($json['dane']); $i++)
{
    foreach($json['dane'][$i] as $key => $value){
		if ($key == 'SERWIS_ID') 
		{
			// Check if user exist on database
			$test = mysqli_query($conn, "SELECT SERWIS_ID FROM users_list WHERE SERWIS_ID='$value'");
            if( $test && $test->num_rows )
			{
				// User exist - check if LOGO OR LOGO_SMALL OR NOTIF is other than on database
				$username = $json['dane'][$i]['SERWIS_NAME'];
				$logo = $json['dane'][$i]['LOGO'];
				$logosmall = $json['dane'][$i]['LOGO_SMALL'];
				$notify = $json['dane'][$i]['NOTIF'];
				$logotest = implode(mysqli_fetch_assoc(mysqli_query($conn, "SELECT LOGO, LOGO_SMALL, NOTIF FROM users_list WHERE SERWIS_ID='$value'")));
				// If all data is same on db and json echo success
				if($logotest == $logo and $logotest == $logosmall and $logotest == $notify)
					{
						echo $username." istnieje w bazie, nie trzeba aktualizowac logo<br/>";
					}
					else
					// If data changed update whole user info
					{
						$sql = "UPDATE users_list SET LOGO='$logo', LOGO_SMALL='$logosmall', NOTIF='$notify' WHERE SERWIS_ID='$value'";
						if (mysqli_query($conn, $sql))
							{
								echo $username." istnieje w bazie. Aktualizowano logo dla ".$username."!<br/>";
							}
						else
							{
								 echo "Error updating record: " . mysqli_error($conn)."<br/>";
							}
					}
					// If user dont exist on database insert it
			} else 
			{
				$userid = $json['dane'][$i]['SERWIS_ID'];
				$username = $json['dane'][$i]['SERWIS_NAME'];
				$logo = $json['dane'][$i]['LOGO'];
				$logosmall = $json['dane'][$i]['LOGO_small'];
				$date = $json['dane'][$i]['DATE'];
				$notify = $json['dane'][$i]['NOTIF'];
				$sql4 = "INSERT INTO users_list (ID,SERWIS_ID,SERWIS_NAME,LOGO,LOGO_SMALL,DATA,NOTIF,ACTIVE) 
				VALUES ('', '$userid', '$username', '$logo', '$logosmall', '$date', '$notify', '1')";
					if (mysqli_query($conn, $sql4))
						{
							// Echo success
							echo "Dodano ".$username." do bazy danych!";
						}
					else
						{
							 echo "Error updating record: " . mysqli_error($conn)."<br/>";
						}
			}
		}
    }
}
// Database table link
echo "<a href='index.php'>Podgląd bazy</a>";
	
?>

 

Podobne pytania

0 głosów
0 odpowiedzi 464 wizyt
pytanie zadane 2 września 2017 w PHP przez marcin99b Szeryf (82,180 p.)
0 głosów
1 odpowiedź 302 wizyt
pytanie zadane 16 sierpnia 2022 w PHP przez Doge Gaduła (3,370 p.)
0 głosów
4 odpowiedzi 276 wizyt
pytanie zadane 21 kwietnia 2018 w PHP przez wneku Nowicjusz (200 p.)

92,579 zapytań

141,429 odpowiedzi

319,657 komentarzy

61,963 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...