PHP Classes

PHP AJAX REST API 5 Call: Execute SQL queries and return JSON responses

Recommend this page to a friend!
  Info   View files Example   View files View files (59)   DownloadInstall with Composer Download .zip   Reputation   Support forum   Blog    
Ratings Unique User Downloads Download Rankings
Not yet rated by the usersTotal: 259 All time: 7,806 This week: 107Up
Version License PHP version Categories
api5_sql2json 1.0GNU General Publi...5PHP 5, Databases, Web services, AJAX
Description 

Author

This package can execute SQL queries and return JSON responses.

It can take request passing a SQL query and it executes the query to return the response results encoded as a JSON string.

The package can restrict the access to query results to HTTP requests that pass an API access authorization token string value, so it can be used in browser side API HTTP requests sent via AJAX.

Requests can also be authenticated using a given password generated by the package.

The class parses the SQL string before executing to make it easy to process and eventually prevent security attacks.

The database access queries can be done to several different types of SQL databases supported by this package.

Picture of Santo Nuzzolillo
  Performance   Level  
Name: Santo Nuzzolillo <contact>
Classes: 3 packages by
Country: Venezuela Venezuela
Age: 61
All time rank: 268511 in Venezuela Venezuela
Week rank: 312 Up2 in Venezuela Venezuela Up
Innovation award
Innovation award
Nominee: 2x

Example

<?php

/*
 +-----------------------------------------------------------------------+
 | This file is part of API5 RESTful SQLtoJSON |
 | Copyright (C) 2007-2018, Santo Nuzzolillo |
 | |
 | Licensed under the GNU General Public License version 3 or |
 | any later version with exceptions for skins & plugins. |
 | See the LICENSE file for a full license statement. |
 | |
 | Pduction |
 | Date : 02/12/2018 |
 | Time : 05:30:44 PM |
 | Version: 0.0.1 |
 +-----------------------------------------------------------------------+
 | Author: Santo Nuzzolilo <snuzzolillo@gmail.com> |
 +-----------------------------------------------------------------------+
*/




set_error_handler("all_errors_handler", E_ALL);
register_shutdown_function( "check_for_fatal" );

function
check_for_fatal()
{
   
$error = error_get_last();
    if (
$error["type"] == E_ERROR ) {
       
ob_clean();

       
error_manager(addslashes("API5 unhandled exception (type=" . $error["type"] . ") \""
           
. $error["message"]
            .
"\" -> " . $error["file"]
            .
" on " . $error["line"] . "")
            , -
20999);
            }
}

function
all_errors_handler($errno, $errstr, $errfile, $errline) {
   
error_manager(addslashes("API5 unhandled exception $errno:$errstr -> $errfile on $errline"), -20998);
}



define("RelativePath", "..");
define("PathToCurrentPage", "/services/");
define("FileName", "api5.php");

require_once(
RelativePath . "/Common.php");
require_once(
RelativePath . "/services/dosqlClasses.php");
include_once(
RelativePath . "/services/cryptojs-aes/cryptojs-aes.php");
include_once(
RelativePath . "/services/cryptojs-aes/cryptojs-aes.php");
require_once
RelativePath . '/services/JWT/Firebase/JWT.php';




global
$CONFIG;
$CONFIG = file_get_contents("../textdb/default.config.php");
$CONFIG = json_decode_and_validate(clsCore::getSqlParsed(clsCore::sqlSplitFromStringWithTags($CONFIG,'config'),'config'),'API5');

global
$AESpassPhrase;
$AESpassPhrase = isset($CONFIG->AESpassPhrase) ? $CONFIG->AESpassPhrase : "" ;

$tokenKey = isset($CONFIG->tokenKey) ? $CONFIG->tokenKey : "";

$headers = apache_request_headers();


if(isset(
$_SERVER["CONTENT_TYPE"]) && strpos($_SERVER["CONTENT_TYPE"], "application/json") !== false) {
       
$_POST = array_merge($_POST, (array) json_decode(trim(file_get_contents('php://input')), true));
   
$_POST = array_merge($_POST, clsCore::parse_raw_http_request());
                }

$token = CCGetFromPost("token", "");

if (!
$token) {
    if (isset(
$headers['Authorization'])) {
       
$matches = array();
       
preg_match('/token=(.*)/', $headers['Authorization'], $matches);
        if (isset(
$matches[1])) {
           
$token = $matches[1];
        }
    }
}

header('Content-type:application/json;charset=utf-8');
ini_set('memory_limit', '-1');
set_time_limit(0);

if (!
$token and $CONFIG->tokenRequired) {
   
error_manager('Auhorization : Token required ', "SYS-5");
}

if (
$token != "inside") {
        if (
$CONFIG->tokenRequired) {
       
$decoded = JWT::decode($token, $tokenKey, array('HS256'));
        try {
                       
$appData = json_decode($decoded->data);
            if (
json_last_error()) {
                throw new
Exception ('JSON ERROR ' . json_last_error());
            }
                                            } catch (
Exception $e) {
           
error_manager('Unmanaged Error ( ' . $e . ')', 20001);
        }
    }
   
    if (!isset(
$_SERVER["HTTP_REFERER"])) {
       
error_manager(1);
    }
    if (!isset(
$_SERVER["HTTP_X_REQUESTED_WITH"])) {
       
error_manager('non Ajax request detected from '.$_SERVER["HTTP_REFERER"].' to '.$_SERVER["HTTP_HOST"],2);
    }

   
$REFER = parse_url($_SERVER["HTTP_REFERER"], PHP_URL_HOST);
    if (!
$REFER === $_SERVER["HTTP_HOST"]) {
       
error_manager(3);
    }
   
$XRF = $_SERVER["HTTP_X_REQUESTED_WITH"];
    if (!
strtoupper($XRF) === "XMLHTTPREQUEST") {
       
error_manager('bad Ajax request detected',4);
            }
}






$resultAction = CCGetParam("action", "all");
$action = CCGetParam("action", "all");
$loginType = strtoupper(CCGetParam("logintype", "LOCAL"));

$SQL = CCGetParam("SQL", "");

$BIND = CCGetParam("BIND","{}");
try {
   
$BIND = json_decode($BIND);
    if (
json_last_error()) {
        throw new
Exception ('JSON ERROR '.json_last_error());
    }
} catch (
Exception $e) {
   
error_manager('BAD BINDED values ( '.$e.')', 20002);
}
$SorterName = CCGetParam('sortdatafield');
$SorterDirection = CCGetParam('sortorder');

$sourceName = CCGetParam("sourcename", "default");
$jsonStyle = strtoupper(CCGetParam("jsonstyle", "OBJECT"));

$includeResult = CCGetParam("icluderesult", "1");
$includeInfo = CCGetParam("icludeinfo", "1");
$includeHeader = CCGetParam("icludeheader", "1");
$includeError = CCGetParam("includeerror", "1");



$transactiontype = strtoupper(CCGetParam("transactiontype", CCGetParam("__transaction_type","QUERY")));



$_SESSION["CONNECTED"] = array();
$_SESSION["CONNECTED"][$sourceName] = new stdClass();
if (
$sourceName != 'default'
   
and (!isset($_SESSION["CONNECTED"])
        or !isset(
$_SESSION["CONNECTED"][$sourceName])
    )
) {
    die(
'{"ERROR" : {"CODE":"2","MESSAGE":"NOT CONNECTED TO DATABASE '.$sourceName.'."}}');
}


if (!
$SQL and !($transactiontype == 'LOGIN' and ($loginType == 'DATABASE' or $loginType == 'OS'))) {
   
error_manager('NON SQL ','SYS-'.'10');
}

    if (!
$sourceName) {
       
error_manager('No datasource (or sourcename) defined ','SYS-'.'11'); }

   
if (!
file_exists("../textdb/" . $sourceName . ".sources.json.php")) {
   
error_manager('Source name (sourcename or datasource) \"'.$sourceName. '\" do not exists.', 'SYS-'.'12');
}
$datasource = file_get_contents("../textdb/" . $sourceName . ".sources.json.php");
$datasource = json_decode_and_validate($datasource, "Setting datasource $sourceName ",true);
if (
json_last_error()) {
    echo
json_last_error_msg()."\n";
}
$CCConnectionSettings[$sourceName] = $datasource;


$DBmetadata = new clsDBdefault();


if (
$transactiontype == 'LOGIN') {
       
APILoginUser($SQL, $loginType);
    die;
} else if (
$transactiontype == 'QUERY') {
               
$sourceSQL = clsCore::sqlBindVariables($SQL, $BIND);
   
               
$Tpl = "";
   
$TemplateFileName = "";
   
$BlockToParse = "";
   
$ComponentName = "";
   
$Attributes = "";

       
$CCSEvents = "";
   
$CCSEventResult = "";
   
$TemplateSource = "";

   
$BlockToParse = "main";
   
$TemplateEncoding = "UTF-8";
       
$ContentType = "application/json";
   
$Charset = $Charset ? $Charset : "utf-8";
   
$PathToRoot = "../";
   
       
$CCSEventResult = CCGetEvent($CCSEvents, "BeforeInitialize", $MainPage);
   
       
$DBmyDB = new clsDBdefault();
   
$MainPage->Connections[$sourceName] = &$DBmyDB;
   
$Attributes = new clsAttributes("page:");
   
$Attributes->SetValue("pathToRoot", $PathToRoot);
   
$MainPage->Attributes = &$Attributes;

           
$WhereCondition = buildWhereCondition();
    if (
$WhereCondition) {
            }

   
           
       
$Result = new clsSqlResult("", $MainPage, $sourceSQL, $WhereCondition, $SorterName, $SorterDirection);

       
$Result->Initialize();


    if (
$action == "headeronly") {

                       
$header = $Result->Metadata->colsbyname;

       
clsCore::returnJson(
           
'{}'
           
, '{"CODE":"0", "MESSAGE" : "SUCCESS"}'
           
, '{"DB_TYPE":"'.$CCConnectionSettings[$sourceName]["Type"].'"}'
           
, $header
       
);
    }


       
$Result->Show();
   

    if (
$action == "dataonly") {
                       
clsCore::returnJson(false, false, false, false, false, $Result->Records);

    }

       
clsCore::returnJson(
               
$Result->Records , $includeError ? '{"CODE":"0", "MESSAGE" : "SUCCESS"}' : false , '{"RECORDS_COUNT":"' . $Result->DataSource->RecordsCount . '", "CURRENT_PAGENUMBER":"' . $Result->PageNumber . '", "CURRENT_PAGESIZE":"' . (strtoupper($Result->PageSize) == 'ALL' ? $Result->RowNumber : $Result->PageSize) . '" }' , $includeHeader ? $Result->Metadata->colsbyname : false );

   
} else if (
$transactiontype == "DML" ){

   
$Result = new clsDMLResult($SQL);

    die;


} else if (
$transactiontype == "TABLE" ){
   
clsCore::sqlTableOperation();
} else if (
$transactiontype == "HRCHY" ){
            include_once
'./dosqlHerachies.php';
       
$c = new clsHierarchiesResult($SQL, $jsonStyle);
    } else {
   
error_manager('Transaction Type "'.$transactiontype. '"" do not exists.', 21);
}

exit;

function
changeFunctions(&$in_obj, &$sec, &$value_arr, &$replace_keys) {
    foreach(
$in_obj as $key => &$value){
                if (
is_object($value) or is_array($value)) changeFunctions($value, $sec, $value_arr, $replace_keys );
        else {
                        if (
strpos($value, 'function(') === 0) {
                               
$value_arr[] = $value;
                               
$value = '%' . $key . '-' . $sec++ . '%';
                               
$replace_keys[] = '"' . $value . '"';
            }
        }
    }

}

function
MetaStandardType($DBtype, $DATAtype, $DATAscale = 0) {
        switch (
$DBtype) {
        case
"ORACLE" : switch($DATAtype) {
                                                           
                                                                                                           
                                                                                                           
            case
"2":
                                if (
$DATAscale > 0) return ccsFloat; else return ccsInteger;
                break;
            case
"182":
            case
"183":
                return
ccsInteger;
                break;
            case
"1":
            case
"8":
            case
"11":
            case
"96":
            case
"112":
            case
"180":
            case
"181":
            case
"231":
                return
ccsText;
                break;
            case
"12":
                return
ccsDate;
                break;
            default : return
null; break;
        }
        case
"MYSQLDESC" : switch($DATAtype) {
            case
"char" :
            case
"varchar" :
            case
"binary" :
            case
"varbinary" :
            case
"blob" :
            case
"text" :
            case
"enum" :
            case
"set" :
                return
ccsText;
                break;
            case
"date" :
            case
"time" :
            case
"datetime" :
            case
"timestamp" :
            case
"year" :
                return
ccsDate;
                break;
            case
"decimal" :
            case
"numeric" :
            case
"float" :
            case
"double" :
            case
"dec" :
            case
"fixed" :
            case
"real" :
            case
"bit" :
                return
ccsFloat;
                break;
            case
"tinyint" :
            case
"smallint" :
            case
"mediumint" :
            case
"int" :
            case
"bigint" :
                return
ccsInteger;
                break;
            default: return
ccsText;
                break;
        }
        case
"MYSQL" : switch($DATAtype) {
                                                                                                                                                                        case
"string":
                return
ccsText;
                break;
            case
"timestamp":
            case
"year":
            case
"int":
            case
"time":
                return
ccsInteger;
                break;
            case
"real":
                return
ccsFloat;
                break;
            case
"date":
                return
ccsDate;
                break;
                                                default: return
ccsText; break;
        }
        case
"MYSQLI" : switch($DATAtype) {
                                                                                                                                                                                                                                                                                                                                                                                                            case
"1" :
            case
"2" :
            case
"3" :
            case
"8" :
            case
"9" :
            case
"11" :
            case
"13" :
                return
ccsInteger;
                break;
            case
"4" :
            case
"5" :
            case
"6" :
            case
"246" :
                return
ccsFloat;
                break;
            case
"7" :
            case
"10" :
            case
"12" :
                return
ccsDate;
                break;
            case
"252" :
            case
"253" :
            case
"254" :
                return
ccsText;
                break;
            default: return
ccsText; break;
        }
    }
    return
null;
}


function
mysqliMetadata(& $db) {
   
$id = $db->Query_ID;
   
$META = new stdClass();

   
$i = 0;
   
$META->cols = array();
    while (
$property = mysqli_fetch_field($id)) {
       
$col = strtolower($property->name);
       
$type = $property->type;
       
$standarType = MetaStandardType("MYSQLI",$type);

       
$META->colsbyname[ "$col" ] = new stdClass();
       
$META->colsbyname[ "$col" ]->{"type"} = $standarType ;
       
$META->colsbyname[ "$col" ]->{"type_raw"} = $type;
       
$META->colsbyname[ "$col" ]->{"size"} = intval($standarType == 3 ? $property->length / 3 : $property->length);
       
$META->colsbyname[ "$col" ]->{"precision"} = $property->decimals;
       
$META->colsbyname[ "$col" ]->{"scale"} = $property->decimals;
       
$META->colsbyname[ "$col" ]->{"is_null"} = !(MYSQLI_NOT_NULL_FLAG & $property->flags) ; $META->colsbyname[ "$col" ]->{"primary_key"} = !(!(MYSQLI_PRI_KEY_FLAG & $property->flags)) ; $META->colsbyname[ "$col" ]->{"auto_increment"} = !(!(MYSQLI_AUTO_INCREMENT_FLAG & $property->flags)) ;
                               
       
$META->cols[ $i ] = new stdClass();
       
$META->cols[ $i ]->{"type"} = $standarType;
       
$META->cols[ $i ]->{"type_raw"} = $type;
       
$META->cols[ $i ]->{"size"} = $property->length;
       
$META->cols[ $i ]->{"precision"} = $property->decimals;
       
$META->cols[ $i ]->{"scale"} = $property->decimals;
       
$META->cols[ $i ]->{"is_null"} = !(MYSQLI_NOT_NULL_FLAG & $property->flags) ; $META->cols[ $i ]->{"primary_key"} = !(!(MYSQLI_PRI_KEY_FLAG & $property->flags)) ; $META->cols[ $i ]->{"auto_increment"} = !(!(MYSQLI_AUTO_INCREMENT_FLAG & $property->flags)) ; $i++;
                                                                                       
                                       
                       
                                                                                                                                                                                               

                                                                      }
            return
$META;
}

function
oracleMetadata(& $db) {
   
$id = $db->Query_ID;
   
$META = new stdClass();

       
   
$META->cols = array();
    for(
$ix=1;$ix<=OCINumcols($id);$ix++) {
       
$col = oci_field_name($id, $ix);
       
$type = oci_field_type_raw($id,$ix);
       
$presicion = oci_field_precision($id,$ix);
       
$escala = oci_field_scale($id,$ix);
       
$standarType = MetaStandardType("ORACLE",$type, $escala);
       
       
$META->colsbyname[ "$col" ] = new stdClass();
       
$META->colsbyname[ "$col" ]->{"type"} = $standarType;
       
$META->colsbyname[ "$col" ]->{"precision"} = $presicion;
       
$META->colsbyname[ "$col" ]->{"scale"} = $escala;
       
$META->colsbyname[ "$col" ]->{"size"} = oci_field_size($id,$ix);
       
$META->colsbyname[ "$col" ]->{"is_null"} = oci_field_is_null($id,$ix);
       
$META->colsbyname[ "$col" ]->{"type_raw"} = $type;
       
       
$META->cols[ $ix - 1 ] = new stdClass();
       
$META->cols[ $ix - 1 ]->{"type"} = $standarType;
       
$META->cols[ $ix - 1 ]->{"precision"} = $presicion;
       
$META->cols[ $ix - 1 ]->{"scale"} = $escala;
       
$META->cols[ $ix - 1 ]->{"size"} = oci_field_size($id,$ix);
       
$META->cols[ $ix - 1 ]->{"is_null"} = oci_field_is_null($id,$ix);
       
$META->cols[ $ix - 1 ]->{"type_raw"} = $type;
       
                                                                            }
    return
$META;
   
   
}
       
function
metadata(& $db) {
               
       
$re = "/ORDER BY.*?(?=\\s*LIMIT|\\)|$)/mi";
   
$sql = preg_replace($re, "", $db->Parent->Query);
   
   
$tipo = $db->Type;
    if ( !(
CCGetParam("action", "") == "headeronly") or strtoupper($tipo) == 'ORACLE') {
                               
$db->query("select * from ($sql) any_table where 1=2");
        if (
$db->Errors->ToString()) {
            die(
"Error ... " . $this->Errors->ToString());
        }

       
$id = $db->Query_ID;
        if (!
$id){
           
$db->Errors->addError("Metadata query failed: No query specified.");
            return
false;
        }

            }

   
$META = new stdClass();

    switch (
strtoupper($tipo)) {
        case
"ORACLE" :
                        return
oracleMetadata($db);
            break;
        case
"MYSQL" :
                        if (
CCGetParam("action", "") == "headeronly" and CCGetParam("statement_type", "table") == "table") {
                               
$tables = extratTablesOnSQL($db->Parent->Query);
                                if (
count($tables) === 1) {
                                        return
mysqlDescribe($db, $tables[0]);
                } else {
                   
$db->query("select * from ($sql) any_table where 1=2");
                    if (
$db->Errors->ToString()) {
                        die(
"Error ... " . $this->Errors->ToString());
                    }

                   
$id = $db->Query_ID;
                    if (!
$id){
                       
$db->Errors->addError("Metadata query failed: No query specified.");
                        return
false;
                    }

                                        return
mysqliMetadata($db);
                }
            } else {
               
$db->query("select * from ($sql) any_table where 1=2");
                if (
$db->Errors->ToString()) {
                    die(
"Error ... " . $this->Errors->ToString());
                }

               
$id = $db->Query_ID;
                if (!
$id){
                   
$db->Errors->addError("Metadata query failed: No query specified.");
                    return
false;
                }
                if (
$db->DB == "MySQLi") {
                                        return
mysqliMetadata($db);
                } else {
                                        return
mysqlMetadata($db);
                }
            }
            break;
        default: return
false;
    }
     
      return
$META;
}

function
mysqlDescribe(& $db, $table) {
       
$db->query("describe ".$table);
        if (!
$db->Query_ID or $db->Errors->toString()){
        echo
"Hubo error, se muestra? ".$db->Errors->toString()."<br>\n";
       
$db->Errors->addError("Describe query failed: No query specified.");
        return
false;
    }

       
$ix = 0; $META = new stdClass();
    while(
$db->next_record()) {
       
$col = strtolower($db->f("field"));
       
$type = $db->f("type");
       
$precision = 0;
       
$scale = 0;

       
preg_match('#\((.*?)\)#', $type, $match);
        if (isset(
$match[0])) {
           
$precision = $match[0];
           
$type = str_replace($precision,"",$type);
           
$precision = str_replace('(', '', $precision);
           
$precision = str_replace(')', '', $precision);
           
$scale = explode(',',$precision);
           
$precision = $scale[0];
           
$scale = (isset($scale[1]) ? $scale[1] : 0);
        }
       
$standarType = MetaStandardType("MYSQLDESC",$type);


       
$META->colsbyname[ "$col" ] = new stdClass();
       
$META->colsbyname[ "$col" ]->{"type"} = $standarType;
       
$META->colsbyname[ "$col" ]->{"type_raw"} = $type;
       
$META->colsbyname[ "$col" ]->{"size"} = $precision;
       
$META->colsbyname[ "$col" ]->{"precision"} = $precision;
       
$META->colsbyname[ "$col" ]->{"scale"} = $scale;
       
$META->colsbyname[ "$col" ]->{"is_null"} = ($db->f("is_null") == "YES" ? true : false);
       
$META->colsbyname[ "$col" ]->{"flags"} = null;
       
$META->colsbyname[ "$col" ]->{"primary_key"} = ($db->f("key") == "PRI" ? true : false);
       
$META->colsbyname[ "$col" ]->{"auto_increment"} = (strpos($db->f("extra"), 'auto_increment') === false ? false : true);


       
$META->cols[ $ix ] = new stdClass();
       
$META->cols[ $ix ]->{"type"} = $standarType;
       
$META->cols[ $ix ]->{"type_raw"} = $type;
       
$META->cols[ $ix ]->{"size"} = $precision;
       
$META->cols[ $ix ]->{"precision"} = $precision;
       
$META->cols[ $ix ]->{"scale"} = $scale;
       
$META->cols[ $ix ]->{"is_null"} = ($db->f("is_null") == "YES" ? true : false);
       
$META->cols[ $ix ]->{"flags"} = null;
       
$META->cols[ $ix ]->{"primary_key"} = ($db->f("key") == "PRI" ? true : false);
       
$META->cols[ $ix ]->{"auto_increment"} = (strpos($db->f("extra"), 'auto_increment') === false ? false : true);

               
$ix++;
    }
    return
$META;
}

function
extratTablesOnSQL($SQL) {

   
    function
getListTable($text) {

       
$text = preg_replace('/\s+/S', " ", $text); $text = preg_replace('/\n\s*\n/', "\n", $text);
       
        if (
strpos($text, ')')) {
           
$text = substr($text, 0, strpos($text, ')'));
        }
       
       
$t_TABLE = '~\bfrom\b\s*(.*)\s*~si'; preg_match_all($t_TABLE, strtolower($text), $matches);
       
$ts = array();
        if (isset(
$matches[1])) {
                        foreach (
$matches[1] as $r) {
               
$wt = strpos($r, ' join ');
                if (
$wt !== false) {
                    return array();
                }
               
$wt = strpos($r, ' where ');
                if (
$wt !== false) {
                   
$r = substr($r, 0, $wt);
                }
               
$rs = explode(",", $r);
                                                foreach (
$rs as $i => $t) {
                   
$wt = strpos($t, ' as ');
                                        if (
$wt !== false) {
                       
$rs[$i] = trim(substr($t, 0, $wt));
                       
$t = trim(substr($t, 0, $wt));
                       
$ts[] = trim($t);
                    } else {
                       
$t = trim($t);
                       
$wt = strpos($t, ' ');
                                                if (
$wt !== false) {
                           
$rs[$i] = trim(substr($t, 0, $wt));
                           
$t = trim(substr($t, 0, $wt));
                                                       
$ts[] = trim($t);
                        } else {
                           
$ts[] = trim($t);
                        }
                    }
                }
            }
        }
                        return
$ts;
    }

    function
getLastChild($levels, & $tables) {
        if (
is_array($levels)) {
            foreach(
$levels as $i => $level) {
               
getLastChild($level, $tables);
            }
        } else if (
is_object($levels)) {
            if (
count($levels->levels) > 0 ) {
               
getLastChild($levels->levels, $tables);
            } else {
                               
$ts = getListTable($levels->text);
                               
$tables = array_merge($ts,$tables);
                return;
            }
        }
    }

       
$x = array();
   
$x = getFromWhere(strtolower($SQL), $x, 'from', 'where', 0, '(',')');
           
$tables = array();
   
getLastChild($x, $tables);
                   
        return
$tables;
}

function
BindEvents()
{
    global
$Result;
   
$Result->CCSEvents["BeforeShowRow"] = "ResultBeforeShowRow";
}

function
ResultBeforeShowRow(& $sender)
{
   
$ResultBeforeShowRow = true;
   
$Component = & $sender;
   
$Container = & CCGetParentContainer($sender);
    global
$Result;
    foreach (
$Component->Metadata->colsbyname as $col => $prop) {
        if (
$prop->type == ccsText) {
           
$Component->{$col}->SetValue(str_replace(array("\\", '"', "/", "\n" , "\r", "\t", "\b"), array("\\\\", '\"', '\/', '\\n', '', '\t', '\b'), $Component->{$col}->GetValue()));
        }
    }

    return
$ResultBeforeShowRow;
}

function
json_validate($string,$flag=false)
{
       
$string = str_replace("\n", "", $string);
   
$string = str_replace("\r", "", $string);
   
$string = str_replace("\t", " ", $string);


       
$result = json_decode($string, $flag);

        switch (
json_last_error()) {
        case
JSON_ERROR_NONE:
           
$error = ''; break;
        case
JSON_ERROR_DEPTH:
           
$error = 'The maximum stack depth has been exceeded.';
            break;
        case
JSON_ERROR_STATE_MISMATCH:
           
$error = 'Invalid or malformed JSON.';
            break;
        case
JSON_ERROR_CTRL_CHAR:
           
$error = 'Control character error, possibly incorrectly encoded.';
            break;
        case
JSON_ERROR_SYNTAX:
           
$error = 'Syntax error, malformed JSON.';
            break;
                case
JSON_ERROR_UTF8:
           
$error = 'Malformed UTF-8 characters, possibly incorrectly encoded.';
            break;
                case
JSON_ERROR_RECURSION:
           
$error = 'One or more recursive references in the value to be encoded.';
            break;
                case
JSON_ERROR_INF_OR_NAN:
           
$error = 'One or more NAN or INF values in the value to be encoded.';
            break;
        case
JSON_ERROR_UNSUPPORTED_TYPE:
           
$error = 'A value of a type that cannot be encoded was given.';
            break;
        default:
           
$error = 'Unknown JSON error occured.';
            break;
    }

    if (
$error !== '') {
                exit(
$error);
    }

        return
$result;
}

function
json_decode_and_validate($string,$in_case_error,$flag=false)
{
       
$string = str_replace("\n", "", $string);
   
$string = str_replace("\r", "", $string);
   
$string = str_replace("\t", " ", $string);

           
$result = json_decode($string, $flag);

        switch (
json_last_error()) {
        case
JSON_ERROR_NONE:
           
$error = ''; break;
        case
JSON_ERROR_DEPTH:
           
$error = 'The maximum stack depth has been exceeded.';
            break;
        case
JSON_ERROR_STATE_MISMATCH:
           
$error = 'Invalid or malformed JSON.';
            break;
        case
JSON_ERROR_CTRL_CHAR:
           
$error = 'Control character error, possibly incorrectly encoded.';
            break;
        case
JSON_ERROR_SYNTAX:
           
$error = 'Syntax error, malformed JSON.';
            break;
                case
JSON_ERROR_UTF8:
           
$error = 'Malformed UTF-8 characters, possibly incorrectly encoded.';
            break;
                case
JSON_ERROR_RECURSION:
           
$error = 'One or more recursive references in the value to be encoded.';
            break;
                case
JSON_ERROR_INF_OR_NAN:
           
$error = 'One or more NAN or INF values in the value to be encoded.';
            break;
        case
JSON_ERROR_UNSUPPORTED_TYPE:
           
$error = 'A value of a type that cannot be encoded was given.';
            break;
        default:
           
$error = 'Unknown JSON error occured.';
            break;
    }

    if (
$error !== '') {
               
error_manager($in_case_error." : ".$error, -20301);
    }

        return
$result;
}

function
error_manager($msg, $code=3, $status = 400)
{
   
$e = new stdClass();
   
$e->{'ERROR'} = new stdClass();
   
http_response_code($status);
    if (
$msg == '5') {
       
$e->ERROR->{'CODE'} = $code;
       
$e->ERROR->{'MESSAGE'} = "BAD REQUEST $msg";
            } else {
       
$e->ERROR->{'CODE'} = $code;
       
$e->ERROR->{'MESSAGE'} = $msg;
       
$e->ERROR->{'USERID'} = CCGetSession("USERID");
            }
    die(
json_encode($e));
}

function
buildWhereCondition() {
                   
       
$filterscount = CCGetParam("filterscount", "0");
   
$where = "";
            if (
$filterscount) {
       
$where = " (";
       
$tmpdatafield = "";
       
$tmpfilteroperator = "";
       
$valuesPrep = "";
       
$values = [];
        for (
$i = 0; $i < $filterscount; $i++) {

           
$filtervalue = CCGetParam("filtervalue" . $i); $filtercondition = CCGetParam("filtercondition" . $i); $filterdatafield = CCGetParam("filterdatafield" . $i); $filteroperator = CCGetParam("filteroperator" . $i);
            if (
$tmpdatafield == "") {
               
$tmpdatafield = $filterdatafield;
            } else if (
$tmpdatafield <> $filterdatafield) {
               
$where .= ")AND(";
            } else if (
$tmpdatafield == $filterdatafield) {
                if (
$tmpfilteroperator == 0) {
                   
$where .= " AND ";
                } else
$where .= " OR ";
            }
                        switch (
$filtercondition) {
                case
"CONTAINS":
                   
$condition = " LIKE ";
                   
$value = "%{$filtervalue}%";
                    break;

                case
"DOES_NOT_CONTAIN":
                   
$condition = " NOT LIKE ";
                   
$value = "%{$filtervalue}%";
                    break;

                case
"EQUAL":
                   
$condition = " = ";
                   
$value = $filtervalue;
                    break;

                case
"NOT_EQUAL":
                   
$condition = " <> ";
                   
$value = $filtervalue;
                    break;

                case
"GREATER_THAN":
                   
$condition = " > ";
                   
$value = $filtervalue;
                    break;

                case
"LESS_THAN":
                   
$condition = " < ";
                   
$value = $filtervalue;
                    break;

                case
"GREATER_THAN_OR_EQUAL":
                   
$condition = " >= ";
                   
$value = $filtervalue;
                    break;

                case
"LESS_THAN_OR_EQUAL":
                   
$condition = " <= ";
                   
$value = $filtervalue;
                    break;

                case
"STARTS_WITH":
                   
$condition = " LIKE ";
                   
$value = "{$filtervalue}%";
                    break;

                case
"ENDS_WITH":
                   
$condition = " LIKE ";
                   
$value = "%{$filtervalue}";
                    break;

                case
"NULL":
                   
$condition = " IS NULL ";
                   
$value = "%{$filtervalue}%";
                    break;

                case
"NOT_NULL":
                   
$condition = " IS NOT NULL ";
                   
$value = "%{$filtervalue}%";
                    break;

                            }
           
$where .= " " . $filterdatafield . $condition . CCToSQL($value, ccsText);
                                    if (
$i == $filterscount - 1) {
               
$where .= ")";
            }
           
$tmpfilteroperator = $filteroperator;
           
$tmpdatafield = $filterdatafield;
        }
                            }
    return
$where;
}

function
end_of_line($text, $i) {
    if (
$i == strlen($text)-1) {
        return
true;
    }
    return
false;
}

function
getFromWhere($text, & $levels, $tagOpen = '(', $tagClosed = ')', $level=0, $groupOpen = '', $groupClose = '' ) {

   
   
$usingGroup = ($groupOpen ? true : false);
   
$inGroup = 0;
   
$max = strlen($text);
   
$start = array();
   
$end = array();
   
$start_tag = array();
   
$end_tag = array();
   
$i = 0;
   
$open = 0;
   
$close = 0;

                    while (
$i <= $max) {
        if (
$usingGroup and substr($text, $i, strlen($groupOpen)) === $groupOpen) {
           
$inGroup++;
                    } else if (
$usingGroup and substr($text, $i, strlen($groupClose)) === $groupClose) {
                       
$inGroup--;
        } else if (
substr($text, $i, strlen($tagOpen)) === $tagOpen and (!$open or !$inGroup)) {
                       
array_push($start, $i);
           
array_push($start_tag, $tagOpen);
           
$open++;
        } else if (
substr($text, $i, strlen($tagClosed)) === $tagClosed and !$inGroup) {
                       
array_push($end, $i);
           
array_push($end_tag, $tagClosed);
           
$close++;
        }

        if (
end_of_line($text, $i)) {
               
array_push($end, $i);
               
array_push($end_tag, ")");
               
$close++;
                        }
        if (
$open == $close and $open) {
            while (
count($start) > 0) {
                               
array_push($levels, new stdClass());
               
$n = count($levels) - 1;
               
$levels[$n]->start = array_shift($start); $levels[$n]->end = array_pop($end);
               
$levels[$n]->endTag = array_pop($end_tag);
               
$levels[$n]->startTag = array_shift($start_tag);
               
$levels[$n]->text = substr($text, $levels[$n]->start, (($levels[$n]->end + (strlen($levels[$n]->endTag) - 1)) - $levels[$n]->start) + 1);
               
$levels[$n]->levels = array();
                                                                               
getFromWhere(
                                       
substr($levels[$n]->text, strlen($levels[$n]->startTag), ($levels[$n]->text - (strlen($levels[$n]->endTag))))
                    ,
$levels[$n]->levels
                   
, $tagOpen
                   
, $tagClosed
                   
, $level + 1
                   
, $groupOpen
                   
, $groupClose);
            }
           
$open = 0;
           
$close = 0;
        }
       
$i++;
    }

        return
$levels;
}

function
APILoginUser($SQL, $loginType = 'LOCAL')
{
    global
$BIND;
    global
$PARAMETERS;

       
CCSetSession('USERNAME', null);
   
CCSetSession('USERID', null );
   
CCSetSession('ROLES', null);
    global
$SYSTEM;
   
$SYSTEM->{'USERNAME'} = CCGetSession('USERNAME');
   
$SYSTEM->{'USERID'} = CCGetSession('USERID');
   
$SYSTEM->{'ROLES'} = CCGetSession('ROLES');
       
   
$bind = is_object($BIND) ? $BIND : new stdClass();

    switch(
strtoupper($loginType)) {
        case
"LOCAL" :
                                                                       
            if (
substr($SQL, 0, 1) == ':') {
                               
$sqlParsed = clsCore::sqlSplitFromFile(substr($SQL, 1));
                                               
$SQL = clsCore::getSqlParsed($sqlParsed, "LOGIN");
            }

           
$db = new clsDBdefault();

           
                       
$SQL = clsCore::getSqlParsed($sqlParsed, "LOGIN");
           
$SQL = clsCore::sqlSetParameters(
               
$db , $SQL , $bind );


           
$db->query($SQL);

                        if (
$db->Errors->ToString()) {
               
error_manager($db->Errors->ToString(), -20101);
            }

                       
clsCore::getBindValues($db);

            if (isset(
$sqlParsed["ROLES"])) {
                               
$SQL = clsCore::getSqlParsed($sqlParsed, "roles");

                                               
$bind->{'username'} = $PARAMETERS->{"PARAMETERS.USERNAME"}->value;
               
$bind->{'userid'} = $PARAMETERS->{"PARAMETERS.USERID"}->value;
               
$bind->{'roles'} = $PARAMETERS->{"PARAMETERS.ROLES"}->value;

               
$SQL = clsCore::sqlSetParameters(
                   
$db , $SQL , $bind );


               
$db->query($SQL);
                while (
clsCore::simplifyNextRecord($db)) {
                    if (!
is_array($PARAMETERS->{"PARAMETERS.ROLES"}->value))
                       
$PARAMETERS->{"PARAMETERS.ROLES"}->value = array();

                   
$PARAMETERS->{"PARAMETERS.ROLES"}->value[] = $db->Record['role'];
                }
            }

            break;

        case
"DATABASE" :
                                   
$db = new clsDBdefault($bind->username, $bind->password);
           
$connect = $db->Provider->try_connect();
                                    if (!
$connect) error_manager("Invalid username/password for DATABASE Login", "SYS-"."0001");

           
$PARAMETERS->{"PARAMETERS.USERNAME"} = new stdClass();
           
$PARAMETERS->{"PARAMETERS.USERNAME"}->value = $bind->username;
           
$PARAMETERS->{"PARAMETERS.USERNAME"}->original_name = 'username';

           
$PARAMETERS->{"PARAMETERS.ROLES"} = new stdClass();
           
$PARAMETERS->{"PARAMETERS.ROLES"}->value = 'CONNECTED';
           
$PARAMETERS->{"PARAMETERS.ROLES"}->original_name = 'roles';

           
$PARAMETERS->{"PARAMETERS.USERID"} = new stdClass();
           
$PARAMETERS->{"PARAMETERS.USERID"}->value = $bind->username;
           
$PARAMETERS->{"PARAMETERS.USERID"}->original_name = 'userid';
                        break;
        case
"OS" :
           
$authorized = false;

                                                                                               
                       
$file = dirname(__FILE__). "/.htpasswd";

            function
crypt_apr1_md5($plainpasswd, $crypted) {
                                                                                               
               
$salt = substr($crypted, 6, strpos(substr($crypted,6), '$'));

               
$translateTo = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
               
$len = strlen($plainpasswd);
               
$text = $plainpasswd.'$apr1$'.$salt;
               
$bin = pack("H32", md5($plainpasswd.$salt.$plainpasswd));
               
$tmp="" ;
                for(
$i = $len; $i > 0; $i -= 16) { $text .= substr($bin, 0, min(16, $i)); }
                for(
$i = $len; $i > 0; $i >>= 1) { $text .= ($i & 1) ? chr(0) : $plainpasswd{0}; }
               
$bin = pack("H32", md5($text));
                for(
$i = 0; $i < 1000; $i++) {
                   
$new = ($i & 1) ? $plainpasswd : $bin;
                    if (
$i % 3) $new .= $salt;
                    if (
$i % 7) $new .= $plainpasswd;
                   
$new .= ($i & 1) ? $bin : $plainpasswd;
                   
$bin = pack("H32", md5($new));
                }
                for (
$i = 0; $i < 5; $i++) {
                   
$k = $i + 6;
                   
$j = $i + 12;
                    if (
$j == 16) $j = 5;
                   
$tmp = $bin[$i].$bin[$k].$bin[$j].$tmp;
                }
               
$tmp = chr(0).chr(0).$bin[11].$tmp;
               
$tmp = strtr(strrev(substr(base64_encode($tmp), 2)),
                   
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
                   
$translateTo);

                return
'$apr1$'.$salt.'$'.$tmp;
            }

                                    function
load_htpasswd($file)
            {
                                if ( !
file_exists($file))
                    return Array();

               
$res = Array();
                foreach(
file($file) as $l)
                {
                   
$array = explode(':',$l);
                   
$user = $array[0];
                   
$pass = chop($array[1]);
                   
$res[$user] = $pass;
                }
                return
$res;
            }

                                    if (isset(
$_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
                               
$pass = $_SERVER['PHP_AUTH_PW'];
               
$user = $_SERVER['PHP_AUTH_USER'];
                                               
$users = load_htpasswd($file);

                if (isset(
$users[$user])) {
                                       
$pass = crypt_apr1_md5($pass, $users[$user]);
                                       
                    if (isset(
$users[$user]) && ($users[$user] == $pass)) {
                       
$PARAMETERS->{"PARAMETERS.USERNAME"} = new stdClass();
                       
$PARAMETERS->{"PARAMETERS.USERNAME"}->value = $user;
                       
$PARAMETERS->{"PARAMETERS.USERNAME"}->original_name = 'username';

                       
$PARAMETERS->{"PARAMETERS.ROLES"} = new stdClass();
                       
$PARAMETERS->{"PARAMETERS.ROLES"}->value = '';
                       
$PARAMETERS->{"PARAMETERS.ROLES"}->original_name = 'roles';

                       
$PARAMETERS->{"PARAMETERS.USERID"} = new stdClass();
                       
$PARAMETERS->{"PARAMETERS.USERID"}->value = $user;
                       
$PARAMETERS->{"PARAMETERS.USERID"}->original_name = 'userid';
                       
$authorized = true;
                    }
                }

                if (!
$authorized) {
                   
header('WWW-Authenticate: Basic Realm="Login please"');
                   
$_SESSION = array();
                   
error_manager("Invalid username/password for OS Login", "SYS-002");
                }

            } else {
               
header('WWW-Authenticate: Basic Realm="Login please"');
               
$_SESSION = array();
               
error_manager("Well formed Basic Authentication required", "SYS-101", 401);
            }
            break;
        default :
           
error_manager(-20101, "Invalid Login type $loginType");
            break;
    }

        unset(
$PARAMETERS->{"PARAMETERS.PASSWORD"});

       
CCSetSession('USERNAME', $PARAMETERS->{"PARAMETERS.USERNAME"}->value );
   
CCSetSession('USERID', $PARAMETERS->{"PARAMETERS.USERID"}->value );
   
CCSetSession('USERROLES', $PARAMETERS->{"PARAMETERS.ROLES"}->value );
    global
$SYSTEM;
   
$SYSTEM->{'USERNAME'} = CCGetSession('USERNAME');
   
$SYSTEM->{'USERID'} = CCGetSession('USERID');
   
$SYSTEM->{'USERROLES'} = CCGetSession('USERROLES');
   
    global
$CONFIG;
    if (
$CONFIG->autenticationmethod == 'TOKEN') {
               
$token = array(
           
"iss" => "API5"
       
,"sub" => "API5"
       
,"aud" => "user"
       
,"iat" => time()
        ,
"exp" => time()+ (7 * 24 * 60 * 60) ,"nbf" => 1357000000
                   
,"uid" => $SYSTEM->USERID
       
,"data" => '{"username":"'.$SYSTEM->USERNAME.'"'
               
.', "userroles":'.(is_array($SYSTEM->USERROLES) ? json_encode($SYSTEM->ROLES) : '"'.$SYSTEM->USERROLES.'"' ).'}'
       
);

       
       
$jwt = JWT::encode($token, $CONFIG->tokenKey);
       
$PARAMETERS->{"PARAMETERS.TOKEN"} = new stdClass();
       
$PARAMETERS->{"PARAMETERS.TOKEN"}->value = $jwt;
       
$PARAMETERS->{"PARAMETERS.TOKEN"}->original_name = 'token';
       
CCSetSession('USERTOKEN', $PARAMETERS->{"PARAMETERS.TOKEN"}->value );
        global
$SYSTEM;
       
$SYSTEM->{'USERTOKEN'} = CCGetSession('USERTOKEN');
    }
   
$result = clsCore::getBindResult($db);
           
clsCore::returnJson(
       
false , false
       
, false
       
, false
       
, false
       
, $result
   
);
    return
$result;
}

?>


Details

API5

Generic SQL to JSON API RESTful for JavaScritpt Ajax Component<br>

<green>API RESTful Genérico de SQL a JSON para Componentes Ajax de JavaScript</green><br> V.0.0.1<br>

Documentacion Completa visite API5.

<br> <b>INTRODUCCION</b><br> API5 es una "interface" entre el fron-end y una base de datos SQL (para muchos base de datos es sinónimo de back-end) cuyo resultado es una estructura JSON. Podríamos decir que es una interface "SQLtoJSON" (ver ejemplo mas adelante). Ha sido programado en PHP, simplemente porque fue el lenguaje que estuvo a la mano y solo se utiliza como un medio para que JavaScript llegue, lea y opere con una base de datos relacional o RDBMS, pero en ningún momento el programador del front-end requiere elaborar un código PHP.

Definiendo PHP como el Middleware, la tendencia es que sea transparente para el propósito final de la API. (Nota: para esta versión la API ha sido probada con MYSQL y Oracle esperando pronto integrar POSTGRES y MSSQL).

<b>SOBRE MODELO-VISTA-CONTROLADOR</b><br> Si definiéramos API5 dentro del esquema MVC, diríamos que API5 sustituye el modelo de datos por la "base de datos" entera, es decir, la base de datos para que exista tuvo que ser modelada según las necesidades de las reglas de negocio, por lo que se espera que un buen diseño debe contemplar una grafica de entidad relación o algo parecido a ella. Pues este MODELO Entidad-Relación es lo que se convierte en la "M" dentro una arquitectura MVC y la forma de accederlo es a través de la API. La Base de datos bien diseñada es, en si, el MODELO de datos, no hay por que redefinirla, con solo mirar la ENTIDAD-RELACION el programador puede conceptualizar todo el modelo de datos disponible.<br> <br> <b>"SQLtoJSON"</b><br> Es decir a partir desde una Setencia SQL generar la salida en formato JSON. La tendencia de esta interface es hacer uso al máximo de las capacidades del RDBMS de una manera simple e intuitiva para los que ya conocen el lenguaje SQL. Mi recomendación para todo programador, independientemente del lenguaje que utilicen, es que deben estar familiarizados con el lenguaje SQL independientemente del RDBMS involucrado y del lenguaje de programación que dominan. Pero aun así, API5 puede permitir la creación de niveles de abstracción que permitan al desarrollador inexperto en SQL a obtener los datos requeridos desde el MODELO si el grupo de desarrollo mantiene entre sus integrantes un DBA o un conocedor del lenguaje SQL. <br>

INSTALACION

Solo debe copiar el directorio API5 en su servidor WEB y está listo para su uso, puede ser en la raíz o en un sub directorio. <br><br> Requerimientos del lado del servidor<br>

? Apache 2.2 o superior (puede ser IIS)<br>
? PHP 5.4 o superior incluido PHP 7<br>
? Dependiendo de la base de datos debe tener activo los módulos PHP acorde.<br>

Para mysql -> mysqli<br> Para oracle -> oci8<br> <br> Configuración requerida antes de su USO<br> API5 requiere de por lo menos un conector de base de datos, estos se definen en los archivos identificados como "source" ubicado en el sub-directorio /textdb. Existe un archivo llamado "default.source.json.php" el cual contiene información de como conectarse a una base de datos.<br>

Ejemplo para una base de datos MySQL:

{
  "Type"            : "MySQL",
  "DBLib"           : "MySQLi",
  "Database"        : "employees",
  "Host"            : "192.168.1.39",
  "Port"            : "3306",
  "User"            : "demo",
  "Password"        : "onlyfordemo",
  "Encoding"        : ["", "utf8"],
  "Persistent"      : false,
  "DateFormat"      : ["yyyy", "-", "mm", "-", "dd", " ", "HH", ":", "nn", ":", "ss"],
  "BooleanFormat"   : [1, 0, ""],
  "Uppercase"       : false
}

Este ejemplo servirá como base para crear otros "source". Para este caso se indica que la base de datos es MySql y DBLib es el adaptador que indica que es atreves del modulo PHP "php_mysqli"

Ejemplo para una base de datos Oracle:

{
"Type"          :"Oracle",
"DBLib"         :"OracleOCI",
"Database"      :"localhost:1521/ORCL",
"Host"          :"",
"Port"          :"",
"User"          :"user",
"Password"      :"password",
"Encoding"      :"UTF8",
"Persistent"    :false,
"DateFormat"    :["yyyy","-","mm","-","dd","","HH",":","nn",":","ss"],
"BooleanFormat" :[1,0,""],
"Uppercase"     :false
}

LISTO!!

<br> <br> <br> Consideraciones:<br>

  1) Type y DBLib son dependientes y siempre deben tener la pareja combinada. En el pasado Mysql podia utilizar dos librerías distintas, pero en la actualidad solo se utiliza "MySQLi".<br>
  2) DateFormat se sugiere ampliamente mantenerlo inalterable como en  los ejemplos. Para mysql es su formato natural para oracle es seteada de esa manera en lo interno, para estandarizar el output de los tipo de fecha.<br>
  3) Encoding UTF8 como apreciarán es algo distinto entre las dos definiciones, se recomienda considerarlos tal como están para ambos tipos.<br>

<br> Una vez modificado el archivo con los valores correspondientes a su instalación, esta listo para su uso. API5 considera mas configuraciones mas avanzadas que están descritas en la documentación.

USO BASICO

El siguiente es el uso mas primario usando todos los valores por defecto que iremos explicando <br> EJEMPLO 001:<br>

// JAVASCRIPT 
// -------------------------------------------
// TEST WITHOUT JQUERY
var data = new FormData();
data.append('SQL','select * from departments');

var xhr = new XMLHttpRequest();
xhr.open('POST','./services/api5.php',true);
xhr.onload = function(){
	//do something to response
	console.log(JSON.parse(this.responseText));
}
//Required to detect that is a XHR
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");

xhr.send(data);
// -------------------------------------------

// JAVASCRIPT 
// -------------------------------------------
// TEST WITH JQUERY
jQuery.ajax({
	url :'./services/api5.php'
	,type :'post'
	,data : {
		SQL:'select * from departments'
	}
	,success : function(result){
		// en este caso result ya es un objeto JS
		console.log(result);
	}
	,error : function(error){
		console.log(error);
	}
});
// -------------------------------------------

RESULTADO:

{
	"HEADER":{
		"dept_no":{
			"type":3,
			"type_raw":254,
			"size":4,
			"precision":0,
			"scale":0,
			"is_null":false,
			"primary_key":true,
			"auto_increment":false
		},
		"dept_name":{
			"type":3,
			"type_raw":253,
			"size":40,
			"precision":0,
			"scale":0,
			"is_null":false,
			"primary_key":false,
			"auto_increment":false
		}
	},
	"ERROR":{
		"CODE":"0",
		"MESSAGE":"SUCCESS"
	},
	"INFO":{
		"RECORDS_COUNT":"9",
		"CURRENT_PAGENUMBER":"1",
		"CURRENT_PAGESIZE":"9",
		"DB_TYPE":"MySQL"
	},
	"DATA":[
		{"dept_no":"d009","dept_name":"CustomerService"},
		{"dept_no":"d005","dept_name":"Development"},
		{"dept_no":"d002","dept_name":"Finance"},
		{"dept_no":"d003","dept_name":"HumanResources"},
		{"dept_no":"d001","dept_name":"Marketing"},
		{"dept_no":"d004","dept_name":"Production"},
		{"dept_no":"d006","dept_name":"QualityManagement"},
		{"dept_no":"d008","dept_name":"Research"},
		{"dept_no":"d007","dept_name":"Sales"}
	]
}

  Files folder image Files  
File Role Description
Files folder imageapi5 (10 files, 5 directories)
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files  /  api5  
File Role Description
Files folder imageapi5 (7 files, 4 directories)
Files folder imagejs (1 directory)
Files folder imageservices (7 files, 2 directories)
Files folder imagetextdb (2 files)
Files folder imagetextsql (1 file)
  Plain text file Classes.php Class Class source
  Accessible without login Plain text file Common.php Example Example script
  Accessible without login HTML file consola.html Doc. Documentation
  Plain text file db_adapter.php Class Class source
  Plain text file db_array.php Class Class source
  Plain text file db_mysqli.php Class Class source
  Plain text file db_oci8.php Class Class source
  Accessible without login Plain text file db_oracleoci.php Aux. Auxiliary script
  Accessible without login Plain text file en.txt Doc. Documentation
  Accessible without login Plain text file es.txt Doc. Documentation

  Files folder image Files  /  api5  /  api5  
File Role Description
Files folder imagejs (1 directory)
Files folder imageservices (5 files, 2 directories)
Files folder imagetextdb (2 files)
Files folder imagetextsql (1 file)
  Plain text file Classes.php Class Class source
  Accessible without login Plain text file Common.php Example Example script
  Plain text file db_adapter.php Class Class source
  Plain text file db_array.php Class Class source
  Plain text file db_mysqli.php Class Class source
  Plain text file db_oci8.php Class Class source
  Accessible without login Plain text file db_oracleoci.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  api5  /  js  
File Role Description
Files folder imagecryptojs-aes (2 files)

  Files folder image Files  /  api5  /  api5  /  js  /  cryptojs-aes  
File Role Description
  Accessible without login Plain text file aes-json-format.js Data Auxiliary data
  Accessible without login Plain text file aes.js Data Auxiliary data

  Files folder image Files  /  api5  /  api5  /  services  
File Role Description
Files folder imagecryptojs-aes (3 files)
Files folder imageJWT (1 file, 1 directory)
  Accessible without login Plain text file api5-jwt.php Example Example script
  Accessible without login Plain text file api5.php Example Example script
  Plain text file dosqlClasses.php Class Class source
  Plain text file dosqlHerachies.php Class Class source
  Accessible without login Plain text file getpage.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  api5  /  services  /  cryptojs-aes  
File Role Description
  Accessible without login Plain text file cryptojs-aes.php Aux. Auxiliary script
  Accessible without login Plain text file example-js-to-php.php Aux. Auxiliary script
  Accessible without login Plain text file example-php-to-js.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  api5  /  services  /  JWT  
File Role Description
Files folder imageFirebase (5 files)
  Accessible without login Plain text file test1.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  api5  /  services  /  JWT  /  Firebase  
File Role Description
  Plain text file BeforeValidException.php Class Class source
  Plain text file ExpiredException.php Class Class source
  Plain text file JWT.php Class Class source
  Accessible without login Plain text file openssl.php Aux. Auxiliary script
  Plain text file SignatureInvalidException.php Class Class source

  Files folder image Files  /  api5  /  api5  /  textdb  
File Role Description
  Accessible without login Plain text file default.config.php Aux. Auxiliary script
  Accessible without login Plain text file default.sources.json.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  api5  /  textsql  
File Role Description
  Accessible without login Plain text file app.logon.sql.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  js  
File Role Description
Files folder imagecryptojs-aes (2 files)

  Files folder image Files  /  api5  /  js  /  cryptojs-aes  
File Role Description
  Accessible without login Plain text file aes-json-format.js Data Auxiliary data
  Accessible without login Plain text file aes.js Data Auxiliary data

  Files folder image Files  /  api5  /  services  
File Role Description
Files folder imagecryptojs-aes (3 files)
Files folder imageJWT (1 file, 1 directory)
  Accessible without login Plain text file api5-jwt.php Example Example script
  Accessible without login Plain text file api5.php Example Example script
  Plain text file apidosql.php Class Class source
  Accessible without login Plain text file compile.php.php Aux. Auxiliary script
  Plain text file dosqlClasses.php Class Class source
  Plain text file dosqlHerachies.php Class Class source
  Accessible without login Plain text file getpage.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  services  /  cryptojs-aes  
File Role Description
  Accessible without login Plain text file cryptojs-aes.php Aux. Auxiliary script
  Accessible without login Plain text file example-js-to-php.php Aux. Auxiliary script
  Accessible without login Plain text file example-php-to-js.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  services  /  JWT  
File Role Description
Files folder imageFirebase (5 files)
  Accessible without login Plain text file test1.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  services  /  JWT  /  Firebase  
File Role Description
  Plain text file BeforeValidException.php Class Class source
  Plain text file ExpiredException.php Class Class source
  Plain text file JWT.php Class Class source
  Accessible without login Plain text file openssl.php Aux. Auxiliary script
  Plain text file SignatureInvalidException.php Class Class source

  Files folder image Files  /  api5  /  textdb  
File Role Description
  Accessible without login Plain text file default.config.php Aux. Auxiliary script
  Accessible without login Plain text file default.sources.json.php Aux. Auxiliary script

  Files folder image Files  /  api5  /  textsql  
File Role Description
  Accessible without login Plain text file app.logon.sql.php Aux. Auxiliary script

 Version Control Unique User Downloads Download Rankings  
 100%
Total:259
This week:0
All time:7,806
This week:107Up