Passing function result into sqli - php

I'm new to this and I know I'm probably doing this entire thing the wrong way, but I've been at it all day trying to figure it out. I'm realizing there's a big difference between programming a real project of my own rather than just practicing small syntax-code online. So, I lack the experience on how to merge/pass different variables/scopes together. Understanding how to fit everything within the bigger picture is a completely different story for me. Thanks in advance.
What I'm trying to do, is to make the function "selectyacht" output data in a different location from where it's being called (in viewship.php). The output data (in viewship.php) needs to be only certain fields (not everything) returned and those results will be scattered all over the html page (not in a table). In addition to that, I have this variable: "$sqlstatement" (in sqlconn.php) that I'm trying to bring outside the function because I don't want to repeat the connection function every time. I tried a global variable, as much as I shouldn't, and it thankfully it gave me an error, which means I have to find a better way.
Basically my struggle is in understanding how I should structure this entire thing based on two factors:
To allow the second conditional statement in sqlconn.php to be typed
as least often as possible for different "selectyacht" functions
that will come in the future.
To allow the connection instance in sqlconn.php to reside outside the function since it will be used many times for different functions.
Returning data in a different place from where it's being called in viewship.php because the call will be a button press, not the results to be shown.
This is probably very simple, but yet it eludes me.
P.S. Some of this code is a copy/paste from other resources on the internet that I'm trying to merge with my own needs.
sqlconn.php
<?php
$servername = "XXXXXXXX";
$username = "XXXXXXXX";
$password = "XXXXXXXX";
$dbname = "XXXXXXXX";
// Instantiate the connection object
$dbconn = new mysqli($servername, $username, $password, $dbname);
// Check if the connection works or show an error
if ($dbconn->connect_error) {
die("Connection failed: " . $dbconn->connect_error);
}
// Create a query based on the ship's name
function selectyacht($shipname) {
global $sqlstatement;
$sqlstatement = "SELECT * FROM ships WHERE Name=" . "'" . $shipname . "'";
}
// Put the sql statement inside the connection.
// Additional sql statements will be added in the future somehow from other functions
$query = $dbconn->query($sqlstatement);
// Return the data from the ship to be repeated as less as possible for each future function
if ($query->field_count > 0) {
while($data = $query->fetch_assoc()) {
return $data;
}
}
else {
echo "No data found";
}
// Close the connection
$dbconn->close();
?>
viewship.php
<html>
<body>
<?php include 'sqlconn.php';?>
<!-- ship being selected from different buttons -->
<?php selectyacht("Pelorus");?>
<br>
<!-- This is the output result -->
<?php echo $data["Designer"];?>
<?php echo $data["Length"];?>
<?php echo $data["Beam"];?>
<?php echo $data["Height"];?>
</body>
</html>

Mate, I am not sure if I can cover whole PHP coding standards in one answer but I will try to at least direct you.
First of all you need to learn about classes and object oriented programming. The subject itself could be a book but what you should research is autoloading which basically allows you to put your functions code in different files and let server to include these files when you call function used in one of these files. This way you will be able to split code responsible for database connection and for performing data operations (fetching/updating/deleting).
Second, drop mysqli and move to PDO (or even better to DBAL when you discover what Composer is). I know that Internet is full of examples based on mysqli but this method is just on it's way out and it is not coming back.
Next, use prepared statements - it's a security thing (read about SQL injection). Never, ever put external variables into query like this:
"SELECT * FROM ships WHERE Name=" . "'" . $shipname . "'";
Anyone with mean intentions is able to put there string which will modify your query to do whatever he wants eg. erase your database completely. Using prepared statements in PDO your query would look like this:
$stmt = $this->pdo->prepare("SELECT * FROM ships WHERE Name = :ship_name");
$stmt->bindValue(':ship_name', $shipname);
Now to your structure - you should have DB class responsible only for database connection and Ships class where you would have your functions responsible eg. for fetching data. Than you would pass (inject) database connection as an argument to class containing you selectYacht function.
Look here for details how implementation looks like: Singleton alternative for PHP PDO
For
'Returning data in a different place from where it's being called'
If I understand you correctly you would like to have some field to input ship name and button to show its details after clicking into it. You have 2 options here:
standard form - you just create standard html form and submit it with button click redirecting it to itself (or other page). In file where you would like to show results you just use function selectYacht getting ship name from POST and passing it to function selectYacht and then just printing it's results (field by field in places you need them)
AJAX form - if you prefer doing it without reloading original page - sending field value representing ship name via AJAX to other page where you use selectYacht function and update page with Java Script

Related

SELECT WHERE = sybol dont return data

a have an sqlite table
CREATE TABLE "lib" (
"id" INTEGER UNIQUE,
"addr" TEXT UNIQUE,
"data" TEXT,
PRIMARY KEY("id")
)
testing dataset contains:
...
1 arara arararar test
2 unit=comp comp test
...
I use code next to test requests
<? $db = new PDO('sqlite:main.db') or die('Unable to open database');
echo ("qry: ".$_SERVER["QUERY_STRING"]."<br>");
foreach ($db->query("SELECT * FROM lib WHERE addr='".$_SERVER["QUERY_STRING"]."'", PDO::FETCH_ASSOC/*_NUM*/) as $row) {
//echo($row[0].'<br>');
echo($row['addr'].'<br>');
echo($row['data'].'<br>');
}
$db = null; ?>
so, when I do script.php?arara it returns
qry: arara
arara
arararar test
but, when I do script.php?unit=comp it returns no data (just QUERY_STRING)
qry: unit=comp
what wrong with my code?
upd:
this question is not about security
php modified for PDO prepare, now its return no data with any request
<? $db = new PDO('sqlite:main.db') or die('Unable to open database');
echo ("qry: ".$_SERVER["QUERY_STRING"]."<br>");
$qry=$db->prepare("SELECT * FROM lib WHERE addr='?'");
$qry->execute(array($_SERVER["QUERY_STRING"]));
foreach ($qry as $row) {
//foreach ($db->query("SELECT * FROM lib WHERE addr='".$_SERVER["QUERY_STRING"]."'", PDO::FETCH_ASSOC/*_NUM*/) as $row) {
//echo($row[0].'<br>');
echo($row['addr'].'<br>');
echo($row['data'].'<br>');
}
$db = null; ?>
what wrong with my code?
... sadly quite a lot.
I've never seen someone inject the QUERY_STRING straight into a query. How easily corruptable would this string be? If I wanted to inject some malicious sql I just have to write it in. If I make a mistake then the query won't return anything. If I add a new parameter in the future because I want more than a single param then the query fails.
The malicious sql is the most dangerous problem here, the other's are about code maintainability and still very important. Check out this
https://bobby-tables.com/
and this
https://www.w3schools.com/php/php_mysql_prepared_statements.asp
You need to parse the query string so you can check and sanitise the data. Php has an in-built function for this:
https://www.php.net/manual/en/function.parse-str.php
You then should be binding the data in the prepared statement you have now read about.
I don't know if you're in charge of the script calling this, but it seems like POST data would be better for this. GET parameters are visible and stored in web server logs, so you have a security vulnerability with potential personal data. You also then won't need to worry about url_encoding/decoding the string.
//EDIT
to be fair, using PHP's parse_str with decode the url anyway, so that at least will take care of that issue if you can't convert it to post

PHP : integrating static HTML content with resolved PHP variables?

I am working in a project which has the following restriction defined:
My PHP files must not have more than one opening or closing tag.
So it's PHP from top to bottom, but I am allowed to add static content by the means of 'import'.
What are proper/elegant ways to add static HTML content to my PHP index file (like outputting a website menu header or a formular) and at the same time resolve PHP variables inside the file.
Like a formular which makes a HTTP POST (login or register) and displays the previously entered email address in case of a mismatch, etc etc.
One way would be
echo "<form ...> \n <input ... value='$lastemail'>";
But I dislike the quoting. echo <<< EOF is also not great for the purpose imho.
I think HTML code should stay together without separating it into multiple echos so it can be validated.
So I am looking for a good solution to import/integrate static HTML code, like a template system and still resolve PHP variables.
Update:
The restriction is made to not mix HTML and PHP code.
I think I will need an engine/class/function which replaces variables inside a HTML template with PHP code. Like searching for ${variable} and replacing it with the php $variable as if it was PHP code.
I just thought maybe there is already something existing within PHP to solve that.
Update:
Should I oppose the requirement ?
Would be very interesting to hear the oppinion of a professional PHP developer with long history in that area. (On The restriction is made to not mix HTML and PHP code. )
Perhaps you could use a templating system? There are plenty out there for PHP. Some nice ones are (in my opinion):
Twig, which is very small and fast
Smarty, a little larger, but also fast and very popular
The solution that I provide now may seem lengthy and strenuous to enact but would one of the best ways to solve problems with such constraints. Create a database with two tables, one of which would store all the static data i.e. HTML code whereas the other would store dynamic data i.e. data that you want to be personalised. You can then use the database to separately eject dynamic and static data, all using just pure PHP.
<?php
$host = "127.0.0.1";
$user = "root";
$password = "****";
$db = "project";
$txt = NULL;
$conn = mysqli_connect($host, $user, $password, $db);
if(!conn){
header("location:error.htm");
}
$query1 = "SELECT dynamicdata FROM projectdynamicdata WHERE pagename ='index'";
$resultset1 = mysqli_query($conn, $query1);
while($row = mysqli_fetch_assoc($resultset1){
$txt = $row["dynamicdata"];
}
$query2 = "SELECT htmlpage FROM projectstaticdata WHERE pagename='index'";
$resultset2 = mysqli_query($conn, $query);
while($row = mysqli_fetch_assoc($resultset){
echo $row["htmlpage"];
}
mysqli_close($conn);
?>
This is what I would to solve such a problem.

functions for crud operations without specifying database name

I have connected my php web app to mongodb with the help of simplemongophp library. Now what I want is ..the operations like read or update should perform without specifying the database name explicitly and all the crud operations should be in the form of functions.
here is a piece of code i have tried
include ('Db.php');
include ('Dbo.php');
// i dont want to specify the db name explicitly
Db::addConnection(new Mongo(),'two');
function non(){
echo "$this->name is . \n";
}
Dbo::addClass('php','gfyhfh');
Db::batchInsert('gfyhfh',array(
array('name'=>'bjhghgjh','hobbies'=>'distin')));
static function insertion()
{
Db::batchInsert('gfyhfh',array(
array('flower'=>'rose')));
}
?>
This is showing error .so can anyone tell me how do i do it.Thankyou
If you don't tell MongoDB what database it needs then how does it know what database to write to? This goes for SQL techs as well.
There is currently no way of connecting to MongoDB without specifying a database name.

PHP - chained triggers how to create/store?

I have been working with a small team on a small project about fiction world building. I have been assigned with the task of managing triggers/chained behavior of entities (rocks/places/items) that can be triggered in many ways such as throwing a magic rock into the lake and monster X will appear, and continue to trigger the things in a chain until it reaches the end.
I have tried this
$Trigger_123 = new stdClass();
$Trigger_123->name = "Name";
$Trigger_123->renderOn = ? // (object_345->throwedInLakeX) ?
How can I store this in MySQL? Can I have it checked if its a chain part? Also I tried MySQL triggers but I can't find a way to execute PHP on those triggers. Running PHP code on update or delete for example.
Cron jobs was not a option because many things will be added in the future and cron jobs will take a lot of time to finish, I was hoping of finding a more php-based solution.
Edited (adding some additional information)
I tried to implement this in many ways. I ended up with a system of dependecies pretty much like debian packages which I believe is not suited for this.
Database structure
Table "object"
--------------
ID (int)
Name (varchar)
Table "triggers"
----------------
ID (int)
Name (varchar)
Data (blob) // usually, I store php code and use eval to run
Table "attributes"
------------------
ID (int)
attribute (varchar)
value (blob)
Table "object_has_triggers"
---------------------------
ID (int)
ObjectID (int)
TriggerID (int)
Table "object_has_attributes"
-----------------------------
ID (int)
ObjectID (int)
AttributeID (int)
What I want as a result is to make a PHP code snippet execute each time
A database transaction , before is submitted and after to database
A object that has X triggers attached to it, resolve them
Each Trigger that is triggered by X be checked if all dependecies to it are satisfied
Question:
Is something like this even possible to build with PHP Or should I try other scripting languages like python?
what i want as a result is to make a PHP code snippet execute each time
A database transaction , before is submitted and after to database
You should call PHP function in trigger. Write all logic in PHP which required to invoke.
A object that has X triggers attached to it, resolve them
A object that has X triggers attached to it, rather convert it into PHP code or resolve it in PHP.
Each Trigger that is triggered by X be checked if all dependecies to it are satisfied
You can make one database table for saving responses after successful completing trigger. And at last you can check all dependencies are satisfied or not.
For calling PHP function from trigger, see different answers of following posts for different types of solutions.
Invoking a PHP script from a MySQL trigger
A PHP code snippet execute each time a database transaction , before is submitted and after to database
Don't reinvent the wheel, this has an incredible simple solution: have a layer on top of your database calls.
Instead of querying your database directly, call a function (perhaps in an object) that handles the database insertion of triggers. And it is right there that you can add your code to pre and post- process your triggers in whichever way you please.
function processDatabaseInsertion($trigger) {
//Preceding code goes here
//Database transaction goes here
//Post-processing code goes here
}
$Trigger_123 = new stdClass();
$Trigger_123->name = "Name";
$Trigger_123->renderOn = $object_345->throwedInLakeX;
processDatabaseInsertion($Trigger_123);
Over simplified, but you get the idea. I would recommend writing a custom class for your triggers but I wrote it in a procedural style since I don't know if you are familiar with OOP.
A PHP code snippet execute each time a object that has X triggers attached to it, resolve them
Same principle as before. If you use PHP >= 5.3, you can spice it up a bit using closures:
function processDatabaseInsertion($trigger) {
//Preceding code goes here
$trigger->renderOn();
//Database transaction goes here
//Post-processing code goes here
}
$Trigger_123 = new stdClass();
$Trigger_123->name = "Name";
$Trigger_123->renderOn = function() use ($Trigger_123) { doAwesomeThing($Trigger_123); }
processDatabaseInsertion($Trigger_123);
Or otherwise go for a more traditional approach:
function processDatabaseInsertion($trigger) {
//Preceding code goes here
switch($trigger->renderOn) {
case "awesomeThing":
doAwesomeThing($trigger);
break;
case "anotherThing":
break;
default:
break;
}
//Database transaction goes here
//Post-processing code goes here
}
$Trigger_123 = new stdClass();
$Trigger_123->name = "Name";
$Trigger_123->renderOn = "awesomeThing";
processDatabaseInsertion($Trigger_123);
Each Trigger that is triggered by X be checked if all dependecies to
it are satisfied
Can easily be handled by the methods above with some more PHP logic as you will be able to tell. You may want to have for instance a generic function called every time you need to process a trigger which in turns check if dependencies are satistifed and runs the specific trigger if so.
Either way there are better ways to tackle this problem than to use eval or some mysql trigger hacking as you can see :)

Echo SQL query on new page with PHP

I know this is probably a really amateur question, but I can't figure this out and I don't know much about PHP or MySQL.
So I have a really simple script that basically allows a user to submit a couple lines of text and their zipcode, then it write it to a database and returns the results on the site. It's a shoutbox essentially.
My client wants the users to be able to filter the results by zipcode. So I have it all setup, and I have a search input where people type in their zipcode, search, and then the PHP returns the submissions from that zipcode.
While I can get the results to show by themselves echoed from the PHP script, how do I get them to display within a specified div within the site? I want it essentially to store a variable, the zipcode, that a user search by, and then use that once the page refreshes to display an updated list that filters out the results that aren't from that zipcode.
Thanks so much for the help.
Chris
Without getting into rewriting etc.:
When you redirect your page, add a query at the end of it that is the zipcode making sure that you don't send any whitespace and that you have an input in a given format:
search.php?zipcode=90210
Then on your search results page, fetch the variable passed and work as usual:
$zipcode = $_GET['zipcode'];
make sure that the zipcode is properly escaped and filtered for nasties.
Make the HTML page a PHP page (usually by making the extension .php). Replace the target div's content with <?php stuff to get and print results ?>.
If you have PHP installed and configured on the web server, it will take certain files (usually those ending in .php) and run them through PHP's interpreter. The PHP interpreter is invoked anytime there is a <?php in the document and it stops parsing content anytime it meets a ?> within the <?php block.
For instance, to get a web page to print "Hello World!" into a div through PHP, I would do:
<div><?php
print 'Hello World!';
?></div>
OK, I figured it out. I just stored my answer in a SESSION variable so that I could call it in my other PHP files.
Now I have one file processing the request, creating the session and the variable, and then redirecting the page. Then I have a PHP included in the page that grabs the SESSION variable and plugs it into my mysql_query to return the proper result!
Not sure if this is the best way of doing it, but it's working.... If anyone knows of a more elegant solution I would love to know it.
Thanks,
Chris
I suggest you do some tutorials on using PHP and database retrieval with mysqli.
<?php
/* Connect to a MySQL server */
$link = mysqli_connect(
'localhost', /* The host to connect to */
'user', /* The user to connect as */
'password', /* The password to use */
'world'); /* The default database to query */
if (!$link) {
printf("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error());
exit;
}
/* Send a query to the server */
if ($result = mysqli_query($link, 'SELECT Name, Population FROM City ORDER BY Population DESC LIMIT 5')) {
print("Very large cities are:\n");
/* Fetch the results of the query */
while( $row = mysqli_fetch_assoc($result) ){
printf("%s (%s)\n", $row['Name'], $row['Population']);
}
/* Destroy the result set and free the memory used for it */
mysqli_free_result($result);
}
/* Close the connection */
mysqli_close($link);
?>

Categories