Calling Oracle Query Using PHP Function with constructor - javascript

I dont know where my mistake is but i want to store an oracle query inside a function and return that function inside an array.
JobDrop.php
class JobDrop {
private $jobSql = "SELECT VMI.PROJECT_NO JOB FROM VW_MTO_INFO VMI ORDER BY VMI.PROJECT_NO ASC";
function _construct($jobSql){
$this->jobSql = $jobSql;
}
function JobDropdown($conn){
$jobParse = oci_parse($conn, $this->jobSql);
$jobExcErr = oci_execute($jobParse);
if (!$jobExcErr){
$e = oci_error($jobParse);
print htmlentities($e['message']);
print "\n<pre>\n";
print htmlentities($e['sqltext']);
printf("\n%".($e['offset']+1)."s", "^");
print "\n</pre>\n";
} else {
$res = array();
while ($row = oci_fetch_assoc($jobParse)){
$res[] = $row;
}
$listVendor = json_encode($res, JSON_PRETTY_PRINT);
return $listVendor;
}
}
}
and in test.php
include './job_drop.php';
require_once('../../lib/dbinfo.inc.php');
$conn = oci_connect(ORA_CON_UN, ORA_CON_PW, ORA_CON_DB);
$jobdrop = new JobDrop();
$jobdrop->JobDropdown($conn);
var_dump($jobdrop);
but it doesnt show the array inside the browser. it shows the query string instead,
object(JobDrop)#1 (1) { ["jobSql":"JobDrop":private]=> string(74) "SELECT VMI.PROJECT_NO JOB FROM VW_MTO_INFO VMI ORDER BY VMI.PROJECT_NO ASC" }
Please help me where I am doing wrong here

If you want to see the array, do:
$res = $jobdrop->JobDropdown($conn);
var_dump($res);

Related

Check if username is unique [duplicate]

I have been making a login/register system and I am drawing close to finishing my register portion of code. The only problem I am running into is how to make it so that users cannot register with duplicated usernames. I want it to work so that my database won't accept the information, and it will tell the user about the error.
My PHP
<?php
include 'database_connection.php';
if (isset($_POST['formsubmitted'])) {
$error = array(); //Declare An Array to store any error message
if (empty($_POST['name'])) {//if no name has been supplied
$error[] = 'Please Enter a name '; //add to array "error"
} else {
$name = $_POST['name']; //else assign it a variable
}
if (empty($_POST['e-mail'])) {
$error[] = 'Please Enter your Email ';
} else {
if (preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*#([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $_POST['e-mail'])) {
//regular expression for email validation
$Email = $_POST['e-mail'];
} else {
$error[] = 'Your EMail Address is invalid ';
}
}
if (empty($_POST['Password'])) {
$error[] = 'Please Enter Your Password ';
} else {
$Password = $_POST['Password'];
}
if (empty($error)) {
//send to Database if there's no error '
}
}
The best way to prevent duplicate usernames in the database is to add a UNIQUE index for the column
-- Make it unique
ALTER TABLE users ADD UNIQUE (username);
This will prevent duplicate records in the table with the same username. When you try to insert the same one then an error will be generated.
You can then catch the exception in PHP and check the reason. The duplicate constraint SQL error code is 1062.
Here is an example of how to catch this error when using PDO:
$error = [];
$username = 'Dharman';
$pdo = new \PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", 'user', 'password', [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, // make sure the error reporting is enabled!
\PDO::ATTR_EMULATE_PREPARES => false
]);
try {
$stmt = $pdo->prepare('INSERT INTO users(username) VALUE(?)');
$stmt->execute([$username]);
} catch (\PDOException $e) {
if ($e->errorInfo[1] === 1062) {
$error[] = "This username is already taken!";
} else {
throw $e; // let the exception to be processed further
}
}
Here is an example of how to catch this error when using mysqli:
$error = [];
$username = 'Dharman';
// make sure the error reporting is enabled!
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'password', 'test');
$mysqli->set_charset('utf8mb4');
try {
$stmt = $mysqli->prepare('INSERT INTO users(username) VALUE(?)');
$stmt->bind_param('s', $username);
$stmt->execute();
} catch (\mysqli_sql_exception $e) {
if ($e->getCode() === 1062) {
$error[] = "This username is already taken!";
} else {
throw $e; // let the exception to be processed further
}
}
You can do it like this when the user post the username for example and click submit you can write this code using mysqli:
<?php
// make sure the error reporting is enabled!
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'password', 'test');
$mysqli->set_charset('utf8mb4');
$username = $_POST['username'];
$stmt = $conn->prepare("SELECT 1 FROM table_name where username=?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_row();
if ($user) {
$error[] = "This username is already taken!";
}
When you create the column of the user you can make it unique, for example create table users(username varchar(350) not null unique).
There are two things you should do.
Make the user name a primary key in the database table. This is easily done using phpmyadmin.
Validate prior to insert.
For the second step, here's an algorithm. You may implement it in your own way using pdo, mysqli or even mysql (although it's not recommended now).
Algorithm at the end of your code (i.e., if there aren't errors)...
Select records that match the USERNAME supplied in the post.
If it exists, give out an error.
If it doesn't exist, insert it.
I used a PDO and class method, may be of some use.
//function for checking if the user already exists in the database
public function userExists($username)
{
//prepared statements for added security
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
//execute the query
$query->execute([$username]);
$rows = $query->fetchColumn();
//if a row is returned...user already exists
return ($rows > 0);
}
note the prepared statements too - definitely the way forward

HOW TO SOLVE PHP ERROR: Notice: Trying to access array offset on value of type bool [duplicate]

While writing a pdo statement, is it possible to repeat the value of a variable? I mean:
$query = "UPDATE users SET firstname = :name WHERE firstname = :name";
$stmt = $dbh -> prepare($query);
$stmt -> execute(array(":name" => "Jackie"));
Please note that I repeat the ":name" nameholder whereas I provide the value only once. How can I make this work?
The simple answer is: You can't. PDO uses an abstraction for prepared statements which has some limitations. Unfortunately this is one, you have to work-around using something like
$query = "UPDATE users SET firstname = :name1 WHERE firstname = :name2";
$stmt = $dbh -> prepare($query);
$stmt -> execute(array(":name1" => "Jackie", ":name2" => "Jackie"));
In certain cases, such as emulated prepared statements with some versions of the PDO/MySQL driver, repeated named parameters are supported; however, this shouldn't be relied upon, as it's brittle (it can make upgrades require more work, for example).
If you want to support multiple appearances of a named parameter, you can always extend PDO and PDOStatement (by classical inheritance or by composition), or just PDOStatement and set your class as the statement class by setting the PDO::ATTR_STATEMENT_CLASS attribute. The extended PDOStatement (or PDO::prepare) could extract the named parameters, look for repeats and automatically generate replacements. It would also record these duplicates. The bind and execute methods, when passed a named parameter, would test whether the parameter is repeated and bind the value to each replacement parameter.
Note: the following example is untested and likely has bugs (some related to statement parsing are noted in code comments).
class PDO_multiNamed extends PDO {
function prepare($stmt) {
$params = array_count_values($this->_extractNamedParams());
# get just named parameters that are repeated
$repeated = array_filter($params, function ($count) { return $count > 1; });
# start suffixes at 0
$suffixes = array_map(function ($x) {return 0;}, $repeated);
/* Replace repeated named parameters. Doesn't properly parse statement,
* so may replacement portions of the string that it shouldn't. Proper
* implementation left as an exercise for the reader.
*
* $param only contains identifier characters, so no need to escape it
*/
$stmt = preg_replace_callback(
'/(?:' . implode('|', array_keys($repeated)) . ')(?=\W)/',
function ($matches) use (&$suffixes) {
return $matches[0] . '_' . $suffixes[$matches[0]]++;
}, $stmt);
$this->prepare($stmt,
array(
PDO::ATTR_STATEMENT_CLASS => array('PDOStatement_multiNamed', array($repeated)))
);
}
protected function _extractNamedParams() {
/* Not actually sufficient to parse named parameters, but it's a start.
* Proper implementation left as an exercise.
*/
preg_match_all('/:\w+/', $stmt, $params);
return $params[0];
}
}
class PDOStatement_multiNamed extends PDOStatement {
protected $_namedRepeats;
function __construct($repeated) {
# PDOStatement::__construct doesn't like to be called.
//parent::__construct();
$this->_namedRepeats = $repeated;
}
/* 0 may not be an appropriate default for $length, but an examination of
* ext/pdo/pdo_stmt.c suggests it should work. Alternatively, leave off the
* last two arguments and rely on PHP's implicit variadic function feature.
*/
function bindParam($param, &$var, $data_type=PDO::PARAM_STR, $length=0, $driver_options=array()) {
return $this->_bind(__FUNCTION__, $param, func_get_args());
}
function bindValue($param, $var, $data_type=PDO::PARAM_STR) {
return $this->_bind(__FUNCTION__, $param, func_get_args());
}
function execute($input_parameters=NULL) {
if ($input_parameters) {
$params = array();
# could be replaced by array_map_concat, if it existed
foreach ($input_parameters as $name => $val) {
if (isset($this->_namedRepeats[$param])) {
for ($i=0; $i < $this->_namedRepeats[$param], ++$i) {
$params["{$name}_{$i}"] = $val;
}
} else {
$params[$name] = $val;
}
}
return parent::execute($params);
} else {
return parent::execute();
}
}
protected function _bind($method, $param, $args) {
if (isset($this->_namedRepeats[$param])) {
$result = TRUE;
for ($i=0; $i < $this->_namedRepeats[$param], ++$i) {
$args[0] = "{$param}_{$i}";
# should this return early if the call fails?
$result &= call_user_func_array("parent::$method", $args);
}
return $result;
} else {
return call_user_func_array("parent::$method", $args);
}
}
}
In my case this error appeared when I switched from dblib freedts to sqlsrv PDO driver. Dblib driver handled duplicate parameters names with no errors. I have quite complicated dynamic queries with lots of unions and a lot of duplicated params so I used following helper as a workaround:
function prepareMsSqlQueryParams($query, $params): array
{
$paramsCount = [];
$newParams = [];
$pattern = '/(:' . implode('|:', array_keys($params)) . ')/';
$query = preg_replace_callback($pattern, function ($matches) use ($params, &$newParams, &$paramsCount) {
$key = ltrim($matches[0], ':');
if (isset($paramsCount[$key])) {
$paramsCount[$key]++;
$newParams[$key . $paramsCount[$key]] = $params[$key];
return $matches[0] . $paramsCount[$key];
} else {
$newParams[$key] = $params[$key];
$paramsCount[$key] = 0;
return $matches[0];
}
}, $query);
return [$query, $newParams];
}
Then you can use it this way:
$query = "UPDATE users SET firstname = :name WHERE firstname = :name";
$params = [":name" => "Jackie"];
// It will return "UPDATE users SET firstname = :name WHERE firstname = :name1"; with appropriate parameters array
list($query, $params) = prepareMsSqlQueryParams($query, $params);
$stmt = $dbh->prepare($query);
$stmt->execute(params);

PHP Array to Javascript Object no array after console.log

Now there are plenty of people with the same issue and their resolutions have not worked.
Problem
I have a list of Times coming back from a REST call. They are created exactly as they should, except I want them to be stored into a JavaScript Array.
PHP
function getOpenAppts()
{
global $wpdb;
$final_array = "";
$td = date('m/d/Y');
$datetime = new DateTime('tomorrow');
$tm = $datetime->format('Y-m-d');
$startDate = $td;
$endDate = $tm;
$apptTypeID = "23";
$get_loc = $wpdb->get_results('SELECT provid,id FROM location');
foreach($get_loc as $val){
// call to Athena to get open appointments
$res = getOpenAppointments($val->id, $val->provid, $startDate, $endDate, $apptTypeID);
//print_r($res);
// if we got some appointments back strip any that started before now
if (array_key_exists('totalcount', $res) && $res['appointments'] > 0)
{
$tzStr = "America/Los_Angeles";
$tzObject = new DateTimeZone($tzStr);
$nowDT = new DateTime();
$nowDT->setTimezone($tzObject);
//print_r($nowDT);
//print_r("\n");
$appts = array();
for ($i = 0; $i < count($res['appointments']); $i++)
{
$apptDT = new DateTime($res['appointments'][$i]['date']." ".$res['appointments'][$i]['starttime'], $tzObject);
//print_r($apptDT);
//print_r("\n");
if ($nowDT < $apptDT)
$appts[] = $res['appointments'][$i];
}
}
if (count($appts) > 0)
foreach($appts as $data) {
$final_array[] = $data;
}
else
$res; // something went wrong. return error message
}
echo json_encode($final_array);
}
Header.php
<script>
var times = <?php getOpenAppts(); ?>;
console.log(times); //Will display properly
</script>
That is exactly how it should come back!
But.. When I run a console on the variable times (which is in the header making it a global variable. I get this.
It should give me the exact same list that the console.log gave me.
What I Have tried
I ran:
PARSE.json(times);
No effect...
I did in PHP:
json_encode(json_decode($appts),true);
No effect...
What part of this process is incorrect?
You are using time as a global variable.
Since the console.log right after the declaration prints everything fine, you are probably overriding its value somewhere after.
Avoid the most you can global variables, they're evil :)

Getting wrong array length with jQuery and mysqli_num_rows()

I'm adding new data to database table with jQuery. Then i'm getting all content from that table. Problem is i'm getting wrong array size every odd time.If i refresh the page it's getting right array size but when i'm clicking button with jQuery function it's all messed up.
I figure out that
$n = mysqli_num_rows($result);
already return wrong num of rows
Here is the script:
$(document).ready(function(){
$.getallentries = function(){
$.getJSON("entries.php",{action : "getall"},function(data) {
var content_array = $.map(data, function(e) { return e;});
console.log(content_array.length); // to check array size
});
$.addstatic = function(){
$.post("entries.php",{action : "addstatic"});
};
};
$("#adds").on("click",function(){
$.addstatic();
$.getallentries();
});
$.getallentries();
And here is entries.php:
function getall(){
$link = db_connect();
$query= "SELECT * FROM jq";
$result = mysqli_query($link,$query, MYSQLI_STORE_RESULT);// Smart people said MYSQLI_STORE_RESULT should help but it didn't
$n = mysqli_num_rows($result);
for($i = 0 ;$i<$n;$i++)
{
$row=mysqli_fetch_assoc($result);
$b[]=$row;
}
echo json_encode(array($b));
}
function addstatic(){
$link = db_connect();
$statin_Entry = "Static Entry";
$query = "INSERT INTO jq (Entry) VALUES ('$statin_Entry')";
$result = mysqli_query($link,$query);
}
if(isset($_GET['action']) && !empty($_GET['action'])) {
$action = $_GET['action'];
switch($action) {
case 'getall' : getall(); break;
}
}
else {
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'addstatic' : addstatic();break;
case 'removelast' : removelast();break;
// ...etc...
}
}
}
This is log of array length
So the problem again, same array size 143,146,151 and where is 156??
You should call $.getallentries in the callback function of the $.addstatic AJAX call, so that it runs after $.addstatic has finished updating the database.
$.addstatic = function(){
$.post("entries.php",{action : "addstatic"}, $.getallentries);
};
There's no need to use mysqli_num_rows before fetching the rows. You should use a loop like this:
while ($row = mysqli_fetch_assoc($result)) {
$b[] = $row;
}
Also, you're wrapping your array in another array. Just do:
echo json_encode($b);
The way you've written it, console.log(content_array.length) should always log 1, I don't understand how you're getting higher numbers. Are you sure you posted the actual code?
There's no point in use $.map, all it's doing is making a copy of the data array. Just use data itself.
And in your PHP, you don't need to test both isset() and !empty(), because empty() checks if the variable is set first.
You don't need to use MYSQLI_STORE_RESULT, it's the default for that option.

Access to JSON element with Javascript [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 8 years ago.
I have this simple JSON object:
[{"k":51.39920565355378,"B":0.087890625}]
I want to access to k and B with Javascript, here is my code:
var jsonData = JSON.parse(jsonText);
console.log(jsonData.k); //Undefined
It always return me undefined, what ever I try but when I display jsonData, I can see the all description of the JSON object:
console.log(jsonData) //[{"k":51.39920565355378,"B":0.087890625}]
Here is the server code witch retrieve my JSON object:
function getMarkersByTripId($tripId)
{
if ($bdd = mysqli_connect(_BDD_HOST_, _BDD_USERNAME_, _BDD_PASSWORD_, _BDD_NAME_)) {
$sql = 'SELECT DISTINCT `markers` FROM `trip` WHERE `trip_id` = "'.$tripId.'"';
$req = mysqli_query($bdd, $sql);
if ($req) {
$row = mysqli_fetch_row($req);
echo json_encode($row[0]);
}
else {
echo json_encode(array('status' => 'failure'));
}
}
if ($bdd) {
mysqli_close($bdd);
}
}
Function witch add my JSON object into the database:
function actionSaveNewtrip($title, $status, $markers)
{
if ($bdd = mysqli_connect(_BDD_HOST_, _BDD_USERNAME_, _BDD_PASSWORD_, _BDD_NAME_)) {
$markers = mysqli_real_escape_string($bdd, $markers);
$sql = 'INSERT INTO `trip` (title, status, markers) VALUES("'.$title.'", "'.$status.'", "'.$markers.'")';
$req = mysqli_query($bdd, $sql);
if ($req) {
echo json_encode(array('status' => 'success'));
}
else {
echo json_encode(array('status' => 'failure'));
}
}
if ($bdd) {
mysqli_close($bdd);
}
}
$markers is the JSON object that I insert into the database.
I would like to know what I'm doing wrong to access to k and B like an array, thank you.
Your JSON will parse into an array with one object in it. Try
console.log(jsonData[0].k);
The outer [ ] make it an array.
Since it is wrapped in an array, you need to access the first array alement
jsonData[0].k
You can see that it works in the following code snippet:
var jsonData = JSON.parse('[{"k":51.39920565355378,"B":0.087890625}]');
alert(jsonData[0].k)

Categories

Resources