Decoding mixture of array and stdObject to Database - php

I am trying to decode a collection of json files to a mysql database and return the decoded values to a datatable for presentation. I have one table called ec2_instances, and want to send to that table an array of values which are located at cfi configuration which works fine. but have now added a new column called aws account id which is on object rather than an array I have updated the model to include the new column but I am struggling
<?php
function from_camel_case($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$ret = $matches[0];
foreach ($ret as &$match)
{
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
}
return implode('_', $ret);
}
$resource_types = array();
$resource_types['AWS::EC2::Instance'] = 'EC2Instance';
$resource_types['AWS::EC2::NetworkInterface'] = 'EC2NetworkInterface';
$resource_types['AWS::EC2::VPC'] = 'VPC';
$resource_types['AWS::EC2::Volume'] = 'Volume';
$resource_types['AWS::EC2::SecurityGroup'] = 'EC2SecurityGroup';
$resource_types['AWS::EC2::Subnet'] = 'Subnet';
$resource_types['AWS::EC2::RouteTable'] = 'RouteTable';
$resource_types['AWS::EC2::EIP'] = 'EIP';
$resource_types['AWS::EC2::NetworkAcl'] = 'NetworkAcl';
$resource_types['AWS::EC2::InternetGateway'] = 'InternetGateway';
$accounts = DB::table('aws_account')->get();
$account_id = array($accounts);
$account_id_exists = array_add($account_id, 'key', 'value');
foreach(glob('../app/views/*.json') as $filename)
{
//echo $filename;
$data = file_get_contents($filename);
if($data!=null)
{
$decoded=json_decode($data,true);
if(isset($decoded["Message"]))
{
//echo "found message<br>";
$message= json_decode($decoded["Message"]);
if(isset($message->configurationItem))
{
// echo"found cfi<br>";
$insert_array = array();
$cfi = $message->configurationItem;
switch ($cfi->configurationItemStatus)
{
case "ResourceDiscovered":
//echo"found Resource Discovered<br>";
if (array_key_exists($cfi->resourceType,$resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
foreach ($cfi->configuration as $key => $value)
{
if (in_array($key,$resource->fields))
{
$insert_array[from_camel_case($key)] = $value;
}
}
if (array_key_exists($cfi->awsAccountId,$resource_types))
{
$resource = new $resource_types[$cfi->awsAccountId];
foreach ($cfi->awsAccountId as $key => $value)
{
if (in_array($key,$resource->fields))
{
$insert_array[from_camel_case($key)] = $value;
}
}
$resource->populate($insert_array);
if (!$resource->checkExists())
{
$resource->save();

Related

output and call array from class function (rollingcurl)

Excuse my English, please.
I use Rollingcurl to crawl various pages.
Rollingcurl: https://github.com/LionsAd/rolling-curl
My class:
<?php
class Imdb
{
private $release;
public function __construct()
{
$this->release = "";
}
// SEARCH
public static function most_popular($response, $info)
{
$doc = new DOMDocument();
libxml_use_internal_errors(true); //disable libxml errors
if (!empty($response)) {
//if any html is actually returned
$doc->loadHTML($response);
libxml_clear_errors(); //remove errors for yucky html
$xpath = new DOMXPath($doc);
//get all the h2's with an id
$row = $xpath->query("//div[contains(#class, 'lister-item-image') and contains(#class, 'float-left')]/a/#href");
$nexts = $xpath->query("//a[contains(#class, 'lister-page-next') and contains(#class, 'next-page')]");
$names = $xpath->query('//img[#class="loadlate"]');
// NEXT URL - ONE TIME
$Count = 0;
$next_url = "";
foreach ($nexts as $next) {
$Count++;
if ($Count == 1) {
/*echo "Next URL: " . $next->getAttribute('href') . "<br/>";*/
$next_link = $next->getAttribute('href');
}
}
// RELEASE NAME
$rls_name = "";
foreach ($names as $name) {
$rls_name .= $name->getAttribute('alt');
}
// IMDB TT0000000 RLEASE
if ($row->length > 0) {
$link = "";
foreach ($row as $row) {
$tt_info .= #get_match('/tt\\d{7}/is', $doc->saveHtml($row), 0);
}
}
}
$array = array(
$next_link,
$rls_name,
$tt_info,
);
return ($array);
}
}
Output/Return:
$array = array(
$next_link,
$rls_name,
$tt_info,
);
return ($array);
Call:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
function get_match($regex, $content, $pos = 1)
{
/* do your job */
preg_match($regex, $content, $matches);
/* return our result */
return $matches[intval($pos)];
}
require "RollingCurl.php";
require "imdb_class.php";
$imdb = new Imdb;
if (isset($_GET['action']) || isset($_POST['action'])) {
$action = (isset($_GET['action'])) ? $_GET['action'] : $_POST['action'];
} else {
$action = "";
}
echo " 2222<br /><br />";
if ($action == "most_popular") {
$popular = '&num_votes=1000,&production_status=released&groups=top_1000&sort=moviemeter,asc&count=40&start=1';
if (isset($_GET['date'])) {
$link = "https://www.imdb.com/search/title?title_type=feature,tv_movie&release_date=,".$_GET['date'].$popular;
} else {
$link = "https://www.imdb.com/search/title?title_type=feature,tv_movie&release_date=,2018".$popular;
}
$urls = array($link);
$rc = new RollingCurl([$imdb, 'most_popular']); //[$imdb, 'most_popular']
$rc->window_size = 20;
foreach ($urls as $url) {
$request = new RollingCurlRequest($url);
$rc->add($request);
}
$stream = $rc->execute();
}
If I output everything as "echo" in the class, everything is also displayed. However, I want to call everything individually.
If I now try to output it like this, it doesn't work.
$stream[0]
$stream[1]
$stream[3]
Does anyone have any idea how this might work?
Thank you very much in advance.
RollingCurl doesn't do anything with the return value of the callback, and doesn't return it to the caller. $rc->execute() just returns true when there's a callback function. If you want to save anything, you need to do it in the callback function itself.
You should make most_popular a non-static function, and give it a property $results that you initialize to [] in the constructor.. Then it can do:
$this->results[] = $array;
After you do
$rc->execute();
you can do:
foreach ($imdb->results as $result) {
echo "Release name: $result[1]<br>TT Info: $result[2]<br>";
}
It would be better if you put the data you extracted from the document in arrays rather than concatenated strings, e.g.
$this->$rls_names = [];
foreach ($names as $name) {
$this->$rls_names[] = $name->getAttribute('alt');
}
$this->$tt_infos = [];
foreach ($rows as $row) {
$this->$tt_infos[] = #get_match('/tt\\d{7}/is', $doc->saveHtml($row), 0);
}
$this->next_link = $next[0]->getAttribute('href'); // no need for a loop to get the first element of an array

How looks good structure of construct for creating multidimensial array

I am trying to create constructor which creates an multidimensional array. My result should be like this:-
Checkout my array $result_array
For now I have error: Illegal offset type. Note that I have als use __toString() becose I work on xml data.
class Property {
public $xmlClass;
public $elemClass = '';
public $first_array = array();
public $result_array = array();
public $data = '';
public $data2 = '';
public function __construct($xml, $elem) {
$this->xmlClass = $xml;
$this->elemClass = $elem;
foreach ($xml->xpath('//*[#baza]') as $val) {
$this->first_array[] = $val;
foreach ($val->ksiazka as $value) {
$data = $value->$elem->__toString();
$this->result_array[$this->first_array][] = $data;
}
}
}
public function getResult() {
return $this->result_array;
}
}
$result_autor = new Property($xml, 'autor');
$autor = $result_autor->getResult();
You need to change your two foreach() like below:-
foreach($xml->xpath('//*[#baza]') as $val) {
//$this->first_array[] = $val; not needed
foreach($val->ksiazka as $key=> $value){ //check $key here
$data = $value->$elem->__toString();
$this->result_array[$key][] = $data; // add $key hear
}
}
If the above not worked then check this too:-
foreach($xml->xpath('//*[#baza]') as $key=> $val) { //check $key here
//$this->first_array[] = $val; not needed
foreach($val->ksiazka as $value){
$data = $value->$elem->__toString();
$this->result_array[$key][] = $data; // add $key hear
}
}

creating JSON from while loop and foreach loop in php

I am revamping an application that is using PHP on the serverside which outputs JSON format.
{"by":"Industrie LLC","dead":false,"descendants":396,"id":"396","kids":[1,396],"score":396,"time":"396","title":"Industrie LLC","type":"comment","url":"www.nytimes.com"}
as it is i am getting the last column of mysql data.i know it is something with the loops but i have no idea what in specific.
My PHP code is here
$sql_metro_company_doc_legal = "SELECT * FROM ".$configValues['CONFIG_DB_TBL_PRE']."posts where post_type='company'";
$res_metro_company_doc_legal = $dbSocket->query($sql_metro_company_doc_legal);
while($row_metro_company_doc_legal = $res_metro_company_doc_legal->fetchRow()) {
$notice2[] = $row_metro_company_doc_legal[5];
$notice8[] = strtotime($row_metro_company_doc_legal[0]);
$notice9[] = $row_metro_company_doc_legal[0];
$notice3[] = $row_metro_company_doc_legal[0];
$notice = array("id" => "".$row_metro_company_doc_legal[1]."","title"=>"".$row_metro_company_doc_legal[0]."");
$notice10[] = $row_metro_company_doc_legal[0];
$notice6[] = $row_metro_company_doc_legal[0];
$notice11[] = $row_metro_company_doc_legal[5];
$notice7[] = strtotime($row_metro_company_doc_legal[2]);
$notice12[] = 'www.nytimes.com';
$notice7[] = "comment";
}
foreach ($notice2 as $status2) {
$_page['by'] = $status2;
}
foreach ($notice8 as $status8) {
$_page['dead'] = $status8;
}
foreach ($notice9 as $status9) {
$_page['descendants'] = (int)$status9;
}
foreach ($notice3 as $status3) {
$_page['id'] = $status3;
}
foreach ($notice as $status) {
$_page['kids'][] = (int)$status;
}
foreach ($notice10 as $status10) {
$_page['score'] = (int)$status10;
}
foreach ($notice6 as $status6) {
$_page['time'] = $status6;
}
foreach ($notice11 as $status11) {
$_page['title'] = $status11;
}
foreach ($notice7 as $status7) {
$_page['type'] = $status7;
}
foreach ($notice12 as $status12) {
$_page['url'] = $status12;
}
foreach ($notice4 as $status4) {
$_page['parent'] = (int)$status4;
}
foreach ($notice5 as $status5) {
$_page['text'] = $status5;
}
//sets the response format type
header("Content-Type: application/json");
//converts any PHP type to JSON string
echo json_encode($_page);
You need to make a 2-dimensional array in $_page.
$_page = array();
foreach ($notice2 as $i => $status) {
$_page[] = array(
'by' => $status,
'dead' => $status8[$i],
'descendants' => (int)$status9[$i],
'id' => $status3[$i],
// and so on for the rest
);
}
header ("Content-type: application/json");
echo json_encode($_page);

CS:GO Stats Api [GetUserStatsForGame]

I got a problem with the GetUserStatsForGame Api. I used
http://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v0002/?appid=730&key=<<KEY>>&steamid=<<PROFILEID>>.
How can i get the the playerstats?
I already tried this but it dosent work :/
if(!$_SESSION['steamid'] == ""){
include("settings.php");
if (empty($_SESSION['steam_uptodate']) or $_SESSION['steam_uptodate'] == false or empty($_SESSION['steam_personaname'])) {
# $url = file_get_contents("http://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v0002/?appid=730&key=".$steamauth['apikey']."&steamids=".$_SESSION['steamid']);
$content = json_decode($url, true);
$_SESSION['total_kills'] = $content['playerstats']['stats']['total_kills'][0]['value'];
$_SESSION['steam_steamid'] = $content['response']['players'][0]['steamid'];
}
$csgoprofile['total_kills'] = $_SESSION['total_kills'];
}
Please help!
stats is a list of name/value pairs so $content['playerstats']['stats']['total_kills'] isn't going to work.
The path to the total_kills value is $content['playerstats']['stats'][0]['value'] but you can't rely on total_kills being at 0.
You can do:
$key = null;
foreach ($content['playerstats']['stats'] as $key => $stat) {
if ($stat["name"] === "total_kills") {
$key = $index;
}
}
$total_kills = $content['playerstats']['stats'][$key]['value'];
If you also want to read the other stats you could do something like:
$stats = array();
foreach ($content['playerstats']['stats'] as $stat) {
$stats[$stat["name"]] = $stat["value"];
}
$total_kills = $stats["total_kills"];
$total_deaths = $stats["total_deaths"];

php FOR not work

this my code. It create xml file from mysql..
my problem:
for($i=0; $i<count($str_exp1); $i++) // HERE
{
$str_exp2 = explode(",", $str_exp1[$i]);
$newnode->setAttribute("lat", $str_exp2[0]);
$newnode->setAttribute("lng", $str_exp2[1]);
}
for not show the all data... it only show me latest one data.. i cant find where is there problem..
P.S. Sorry for my english
0
$doc = new DOMDocument("1.0");
$node = $doc->createElement("marker");
$parnode = $doc->appendchild($node);
$result = mysql_query("SELECT * FROM usersline");
if(mysql_num_rows($result)>0)
{
header("Content-type: text/xml");
while ($mar = mysql_fetch_array($result))
{
$node = $doc->createElement("line");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("id_line", $mar['id_line']);
$newnode->setAttribute("color", $mar['colour']);
$newnode->setAttribute("width", $mar['width']);
$node = $doc->createElement("point");
$newnode = $parnode->appendChild($node);
$str_exp1 = explode(";", $mar['coordinats']);
for($i=0; $i<count($str_exp1); $i++) // HERE
{
$str_exp2 = explode(",", $str_exp1[$i]);
$newnode->setAttribute("lat", $str_exp2[0]);
$newnode->setAttribute("lng", $str_exp2[1]);
}
}
$xmlfile = $doc->saveXML();
echo $xmlfile;
}
else
{
echo "<p>Ëèíèé íå îáíàðóæåíî!</p>";
}
Your problem is that you set multiple values to the same node. So you are always overwriting the attribute values with the latest lat/long value.
Instead you need to add a new element per each lat/long pair because XML elements do not have duplicate attributes.
Some example code based on your question, as you can see I introduce some functions to keep things more modular:
$result = $db->query("SELECT * FROM usersline");
if (!$result || !count($result)) {
echo "<p>Ëèíèé íå îáíàðóæåíî!</p>";
return;
}
$doc = new DOMDocument("1.0");
$doc->loadXML('<marker/>');
$marker = $doc->documentElement;
foreach ($result as $mar) {
$line = $doc->createElement('line');
$attributes = array_map_array(['id_line', 'colour' => 'color', 'width'], $mar);
element_add_attributes($line, $attributes);
foreach (coordinates_to_array($mar['coordinats']) as $latlong) {
$point = $doc->createElement('point');
element_add_attributes($point, $latlong);
$line->appendChild($point);
}
$marker->appendChild($line);
}
header("Content-type: text/xml");
echo $doc->saveXML();
function element_add_attributes(DOMElement $element, array $attributes)
{
foreach ($attributes as $name => $value) {
if (!is_string($name)) continue;
$element->setAttribute($name, $value);
}
}
function array_map_array(array $map, array $array)
{
$result = array();
foreach ($map as $alias => $name) {
$source = is_string($alias) ? $alias : $name;
$result[$name] = $array[$source];
}
return $result;
}
function coordinates_to_array($coordinates)
{
$result = array();
$coordinatePairs = explode(";", $coordinates);
foreach ($coordinatePairs as $coordinatePair) {
list($pair['lat'], $pair['lng']) = explode(',', $coordinatePair, 2) + ['', ''];
$result[] = $pair;
}
return $result;
}
I hope this example is helpful and shows you some ways how you can put a problem apart so that your code becomes more easy and more stable.
To make use of $db->query(...) first define a class that has the query method:
class DB {
public function query($sql) {
$dbhandle = mysql_query($sql);
$result = array();
while ($mar = mysql_fetch_array($dbhandle))
$result[] = $mar
;
return $result;
}
}
Then instantiate it:
$db = new DB();
You can then use the code above for that part.
For the problem with the PHP 5.4 array notation for example in this line:
$attributes = array_map_array(['id_line', 'colour' => 'color', 'width'], $mar);
First of all extract the array out of it:
$mapping = ['id_line', 'colour' => 'color', 'width'];
$attributes = array_map_array($mapping, $mar);
Then define the array with the array( and ) notation instead of [ and ]:
$mapping = array('id_line', 'colour' => 'color', 'width');
$attributes = array_map_array($mapping, $mar);
Do so as well in other places, e.g.
['', '']
becomes
array('', '')
and similar.
Replace your code with this:
$str_exp1 = explode(";", $mar['coordinats']);
$newnode->setAttribute("lat", $str_exp1[0]);
$newnode->setAttribute("lng", $str_exp1[1]);

Categories