A lot depends on how and what you develop but I can tell you why I find Vagrant invaluable.
I don't have needless services running on my PC. I bring a box up when I need it and halt or destroy it when I don't. It's especially useful as dependencies grow and you end up with memcached or redis or elasticsearch or mongodb floating around in background processes.
Upgrading is easy. With an AMP solution I was wasting a lot of time dealing with breaks and other weirdness a version upgrade could cause. With Vagrant I just provision a box with what I need.
I can constrain a VM to my hosting specs. That makes it easy to test for resource issues before they occur in production. Can I use a little 512MB memory droplet on DigitalOcean or do I need a more robust solution? With Vagrant I can find out.
Testing alternate configurations is easy. Even though it can sometimes take years, software eventually needs to be upgraded as part of its normal life cycle. Maybe I'm going from Apache 2.2 to 2.4 or PHP 5.4 to 7.0 or MySQL to MariaDB. With AMP I'd be forced to manually make all those changes in place and, should they fail or some issue come up, manually revert back.
It prevents edge cases I might not be immediately aware of. Developing on a 64-bit OS but deploying to a 32-bit server? That means different PHP_INT_MAX values. Working on Windows but running on Linux? That means a function like money_format isn't going to work locally.
You need to do a return in greet()
public function greet(){ return "Hello, my name is " . $this->firstname . " " . $this->lastname . ". Nice to meet you! :-)"; }
For more info: http://php.net/manual/en/functions.returning-values.php
An entry point is a file or code which controls how your application initially "starts." For example, if you have a physical PHP page for every part of your website (home.php, index.php, users.php, contact.php, support.php, product.php, view.php, search.php, games.php, etc.)--then you would have LOTS of entry points to your application.
However, if you use CodeIgniter, then you only have a single entry point to your application, which is index.php. You load various parts of your site by passing parameters to the index.php page (index.php?page=home, index.php?page=search, index.php/product/view/13, etc.).
This brings you into the Model, View, Controller (MVC) framework design. Controller's are you "pages", Models are your database queries, and views are your HTML (very basic definition).
With an MVC framework, you use a router to determine which controller and action to run. For example, in CodeIgniter, your URLs look like this: domain.com/product/view/2. Product is your Controller, view is your action (which is a method/function in your controller), and 2 is a parameter you're passing to the view action. You can read up on CodeIgniter's routing here: https://codeigniter.com/user_guide/incoming/routing.html
But seriously though--CodeIgniter has GREAT documentation. I would strongly recommend you read it while playing with a basic site. https://codeigniter.com/user_guide/intro/index.html
There is only one way that you should be hashing in PHP and that's with the password_* functions. There is no point attempting to do it yourself.
https://secure.php.net/manual/en/function.password-hash.php
http://www.sitepoint.com/hashing-passwords-php-5-5-password-hashing-api/
Wow! Good on you for recognizing the problem and challenging yourself to further your programming skills.
Even JavaScript in the same file? Yikes. Of course a directory full of files that all include each other in chains is the very definition of spaghetti. The key is to logically separate areas of concern.
My first and by far my highest recommendation is this book: The Pragmatic Programmer. It's not PHP specific, the skills that book teaches apply to all programming. Buy it, read it, learn it, know it, love it. I've been a professional programmer for years and it's still a book I go back to time and again.
My second recommendation: any other book by the Pragmatic Programmers. Seriously.
Other good books: Code Complete, the PHP Cookbook, Programming PHP.
Now, you're probably at a point where you can branch out and see alternative methodologies. I'd run through a few Django or Rails tutorials (yes, they aren't PHP but the point is to broaden your horizons) and get a feel for how they work. Then you can take the concepts of MVC and incorporate them into your own code.
Speaking of MVC, this is a little dated but very worthwhile: http://oreilly.com/php/archive/mvc-intro.html
Let's see, what else. My typical pattern for a web application is a back end class that handles the data, a page class that extends the back end class that adds code for calling the page header, footer, and other fixed content (e.g. sidebar). The front end pages will be scripts that pull in the page class, initialize it with their title, any specific javascript file links, etc. then use the data methods of the page class (because it extends the data class) to retrieve data, store data, validate input, etc.
Hmm, feel free to ignore that last paragraph as I'm starting to ramble. Although I think it's inspired me to code up a sample bundle of my PHP application pattern. I'll post on github or xyzzyb.com when it's done.
Well $c being int(0) is the expected value.
Your code is searching for the value "a" in the array.
Array_search returns the key the first found entry.
The first entry found was at position 0.
To get all keys you can use array_keys()
From PHP Manual (http://php.net/manual/en/function.array-search.php): > If needle is found in haystack more than once, the first matching key is returned. To return the keys for all matching values, use array_keys() with the optional search_value parameter instead.
tl;dr: There's nothing to worry about here.
All it is is a Dockerfile, and all the files needed inside of the docker environment.
The Dockerengine is a way to isolate applications (like PHP, or Python) in their own environment. These environments are called 'containers'. All this does, is it creates a virtual environment, installs the necessary software (like Apache, opcache, mongodb and Redis) inside this environment, so your computer won't be affected.
Only the volumes
parts in docker-compose.yml
, will affect your computer a little bit. Basically they will place files that are used inside the container, on your computer, outside of the container. This gives developers / users, easy access to configuration files, and other files, without having to go inside of the container.
More explanation: https://www.docker.com/resources/what-container
I think prepered statements will handel that for you. Manual link http://php.net/manual/en/mysqli.quickstart.prepared-statements.php So after prepering your query like in manual use bind_param("ssi", $yourstringhere,$otherstring,$intigervarieble);
Try not to use SHA1 (or MD5) for password hashes. They're pretty damn old and can be cracked very easily by today's computers by the use of rainbow tables.
Instead use something like password_hash(). You can read up on the syntax and how to use it here: http://php.net/manual/en/function.password-hash.php It also "salts" the password, meaning it does "something" to the password to change the hash (like generate a random string and adding it to the password). This means that for example two users that have the same password will have different hashes, increasing security.
I'd suggest ditching bower instead of ditching NPM. Bower is pretty much dead and NPM is great for both front-end and back-end JS these days.
Also use Yarn as a replacement for the NPM command line tool.
Also, Webpack and Rollup have taken a lot of the momentum away from Gulp. It can be a pain to switch if you've got a good Gulp workflow, but at this point I think Gulp has an expiration date.
What you're doing is called the "service locator" pattern. It means you're using a class to locate other services from within other classes. Eg. from a controller. "Dependency Injection" (DI) means you won't lookup those dependencies, but instead inject them into the places you need. Eg. if BlogController
requires a BlogModel
in all of its actions, it means the BlogController
shouldn't be allowed to exist without it. Than you could inject the model via the BlogController
s constructor. If it would be an optional dependency, you could use a setter instead.
But where does that constructor call come from? As far as I know DI can only work to its full extent when all classes who need injection are registered as a service into the container. This container knows how to construct each class because you've either specified the definitions, or use a lot of magic in PHP.
Because this explanation might not suffice, you probably want to take a look at this laracasts video to understand how DI can be done: https://laracasts.com/series/laravel-from-scratch-2017/episodes/24
I'm sorry, but it doesn't even look like you've covered the very basics of learning PHP. Go find a tutorial, like this one and at least cover the intro before posting questions like this here.
So, the problem is, obviously, this line:
>if ($result = mysqli_query ($conn, $statement))
To quote the PHP documentation for the mysqli_query function:
>Returns FALSE on failure.
A SQL DELETE query that doesn't match any rows is not failing, just as a SELECT query that doesn't match any rows doesn't fail - it just returns an empty result set.
Essentially you need to check if your query actually deleted anything. There are a number of ways to do this and I assume it's a school assignment or something so I'm not going to do it for you. You could look into this function as an example though.
The previous poster was alluding to the fact that you are passing user input directly into SQL queries, this is called SQL injection and is a major security vulnerability. You might want to look into prepared statements.
The shortest answer is you don't. You use PDO and prepared statements. They are simpler, more reliable, more readable, and more secure. They are better in every possible way.
There are three basic types of errors in PHP:
Notices: These are small, non-critical errors that PHP encounters while executing a script - for example, accessing a variable that has not yet been defined. By default, such errors are not displayed to the user at all - although the default behavior can be changed.
Warnings: Warnings are more severe errors like attempting to include() a file which does not exist. By default, these errors are displayed to the user, but they do not result in script termination.
Fatal errors: These are critical errors - for example, instantiating an object of a non-existent class, or calling a non-existent function. These errors cause the immediate termination of the script, and PHP's default behavior is to display them to the user when they take place.
It's not about whitespace, or at least not about whitespace in the way you think it is. The error is due to string interpolation and how it expects to find variables.
$string = "foo $bar['baz'] blah"; // T_ENCAPSED_AND_WHITESPACE error $string = "foo $bar[baz] blah"; // no error $string = "foo {$bar['baz']} blah"; // no error $string = "foo $bar[0] blah"; // no error
It's what you get when you quote the array key, or use a complex value inside a string without {}. Since HEREDOC does the same string interpolation as double quotes, you get the same parser problem.
If an error doesn't make sense, the best thing to do is to look up what the token is for. This will often give you a hint about what is "expected" or "unexpected".
The whitespace part comes from the fact that whitespaces are captured as part of the string constant part. For example:
$string = "foo $bar[ baz ] blah"; $string = 'foo $bar[ 0 ]";
would both also produce the T_ENCAPSED_AND_WHITESPACE error because the spaces inside [] become part of the string constant.
yeah, it's how we all start out. Yes, use a framework and learn about MVC Yes, learn object-oriented code, it makes your code a lot cleaner and easier to manage, keeps everything DRY. Check out the samples of PHP/Object oriented code on Laracasts.com
They real question is if you should store code in the DB like this. You lose version control if it's in the DB, unless you implement it yourself. There are also performance implications as the code execution is likely to be worst than include due to the need for dynamic interpretation of the code string.
There is nothing wrong with your str_replace approach but current PHP methods use frameworks with template engines. Where the code is separate from the presentation layer like the example axvk provided.
Read about phalcon or laravel
For a quick fix use eval as suggested, if you hit a performance wall which I doubt you will you could cache the files to disk from the DB and use include instead.
> I'm trying to convert the contents of this page (API) into a PHP Array
That is a JSON encoded data. PHP has a built-in function to decode JSON.
Let's pick apart this complicated expression shall we?
I see you understand this part:
$file = readdir($dh)
Now, one of the quirks of this line is that, not only does it assign the value of readdir
to $file
but that expression as a whole evaluates to whatever readdir
returns. Let's simplify that expression as result
. So what follows is:
!(return) === false
Now, this is a little bit more easier to read eh? Now, if readdir
returns true, we invert it (that's the !
operator) then check if that is equal to false (false === false) which it is so the loop continues. The triple equals simply compares both the values and data types of the operands.
Now, if readdir
returns false (meaning it's done), it is inverted to true which then fails the comparison (true === false) thus, terminating the loop.
As for your second question, it seems like readdir does include the .
and ..
directories. .
represents the directory itself while ..
represents the parent directory. Notice that when you want to change directory to the parent directory via the terminal, you type cd ..
. Here's what I'm talking about. Seems like PHP provides an example to remove these two special entries.
if you want to use sql statements like select then you'd have to use a database. one option is sqlite, a file based database. you could use a library to import csv to sqlite and then run your sql statements.
here's a simple csv to sqlite function: https://gist.github.com/fcingolani/5364532
you can use a simple call like this to create your database. just make sure you properly chmod the folder for writing. http://php.net/manual/en/function.sqlite-open.php
There's the statistics library which you might find of use. In the end, PHP may not be the best language for this sort of thing. There's a good reason scientists usually choose R, Python, and others as their language of choice. The libraries for stats in PHP are pretty sparse.
PHP will do string replacement for you if you use double qoutes around the string.
For your example:
$api = file_get_contents("https://www.googleapis.com/youtube/v3/playlistItemspart=snippet&maxResults=$maxVids&playlistId=$id&key=$key");
See http://php.net/manual/en/language.types.string.php#language.types.string.parsing
You can also do string concatenation like:
$url = "google.com?playlistId=" . $playlistId . "&key=" . $key;
I would recommend using explode then array_chunk
Assuming you want to use the commas as delimiters, keep the colons, remove the parentheses, then get chunks of three items:
//Start with your string $string = "(1,033,00:05,2,092,00:19,3,100,00:28)";
//Remove parentheses $string = preg_replace('/(|)/','', $string);
//Explode into array using comma as delimiter $stringArray = explode(",", $string);
//View your new array print_r($stringArray); echo "<hr>";
//Get three item chunks $chunkedArray = array_chunk($stringArray, 3);
//View them chunks print_r($chunkedArray); echo "<hr>";
//Process the chunks foreach ($chunkedArray as $item) { //Your database stuff here
//Or just see the values echo $item[0] . "<br>"; echo $item[1] . "<br>"; echo $item[2] . "<br>"; echo "<hr>";
}
This is why I love sketches, because I never understand people :D. /u/wh33t is right, you don't need ajax to add rows. I made this codepen for you: https://codepen.io/anon/pen/EvpQwx I commented the jquery code for the first table failures so you will know what is going on. Note that the number columns are readonly and number 1 is added trough html and additional number are added trough javascript.
Upon submiting treat each input name as an array, example:
foreach($_POST['fDescription'] as $fd) //fDescription is an array of values from all columns, fd are the values. { # Do something }
Take a look at uasort.
In this case, you'll want to convert your values into a DateTime object to do the comparison (you can convert them inside your compare function)
I'm not sure what you're trying to do that isn't represented here? What exactly don't you know how to do? It looks like you've got image uploading fine, you just need to have a loop to go through each file?
If they're choosing multiple files, you'll need a place in the database for each - whether that's a column each (ok solution), a separate table to store just images (best solution), or putting a serialized array into a field (least good solution). A few other issues:
First off, use the MIME type of the file, not the extension - anyone can change the extension and execute harmful code on your server.
Second, you should be escaping all data going into the database - it'd be super-easy to exploit this code as-is. Use <code>mysql_real_escape_string</code> for that. Better yet, the mysql_*
functions are deprecated anyway, so using prepared statements with mysqli or PDO are preferred.
Rather than using variable variables, you'd be better served to put everything into an associative array in the first place. This is the more traditional way of handling this sort of data.
E.g.:
$c_array = array( 15 => 'OUI', 16 => 'OUI', // etc. );
print $c_array[15]; // Prints "OUI"
Basically, $status will contain any error codes. So, if its 0 (false), then you successfully returned output. In theory, you could also check with $status > 0
Depending on the file system, you may get an int return code if the thing fails, which will mean something depending on the os/filesystem. Could be permissions, or readonly or ??
So, nobody is going to tell him that this script is fundamentally broken from the start?
Your biggest problem here is that you're copy/pasting bits of code together with no understanding of what exactly they're supposed to do and attempting to use concepts you don't understand. You need to open the manual, and start reading. I'd suggest starting with handling file uploads.
> Is there anyway I can structure this code?
I wrote a book specifically for the situation you describe; it's called Modernizing Legacy Applications in PHP, and it gives very detailed step-by-step instructions to help you convert that mess into something much more well-structured. You don't have to take my word for it; you can read the Sitepoint review, among others.
Good luck!
These other answers are a bit misleading. There's a lot of reasons to use an Object over an Array. Objects are a bit slower, like /u/AegirLeet said, however it's a minor performance boost in the same way that using single quotes are faster than double quotes. I'm not suggesting you use StdClass, but instead build your own Class that adds value for your context.
​
Some reading as to why Objects > Arrays:
https://dev.to/aleksikauppila/dont-return-associative-arrays-28il
What you’re describing could actually mean any number of things. I recommend posting the code you have so far somewhere like http://gist.github.com, and add comments with specific questions. If we see the code, you’ll likely get an answer very quickly.
Resources used by your script should be freed when the script ends. The documentation for mysql_close() says that non-persistent connections will automatically be closed when the script ends as well. In most cases, I don't think there is any issue with letting the system free up resources for you. Personally, sometimes I do unset my variables just so I am explicitly showing that I'm not planning on using them after that point, but unless you're using a lot of memory for your arrays or you have a long-running script I don't think it's technically necessary.
No. But that's not what functions are for.
We use functions and methods to encapsulate / isolate behavior. This makes the code easier to understand, test and change.
For example, using a template function to display content allows a page / site to be completely redesigned with little understanding of what the site code is doing required.
As another example, using a function that sends email allows for the method of sending email to be changed (for example, switching from mail() to PHPMailer, or to a service such as MailChimp), without touching any of the code that wants to send emails.
We also use functions to allow code reuse. If you're sending emails from 10 different places in your application, using a function allows you to centralize the setup of those emails (eg. sender details or wrap the content in a template for branding / unsubscribe links) so that you don't have to do that setup every time you want to send an email.
(You can then take that a step further, and where you find yourself wanting to do the same thing on multiple projects, you can wrap the functions up as a library)
Recommended reading: Clean Code by Robert Martin ("Uncle Bob")
Aside: In PHP, one thing functions do help with is memory management. PHP uses automatic memory allocation and an internal garbage collector so that (generally), the developer doesn't have to worry about managing memory and memory leaks.
Wrapping code in functions provides "break points" at which PHP considers running the garbage collector to free up memory that's no longer used. It also helps because variables are automatically unset when you leave a function.
For the vast majority of code this has no substantial benefit. However, if you're doing some large amount of processing (for example, manipulating images or importing / exporting a large amount of records from the database), this can help to avoid hitting the memory_limit.
For passwords, don't encrypt, hash and salt them instead. There is an API for this built into PHP itself.
As for encrypting the database, it is not impossible, but it is worth thinking about how to go about it. Would you use symmetric encryption based on the user's current password? What happens if they forget their account password? In that situation you'd be able to reset their account password (by overwriting the hash in the database, based on a "forgot password" email) but you'd not be able to recover the accounting data.
It's worth noting that encryption can play havoc with ordinary database features. If you want to encrypt the dates of transactions, then you can no longer ORDER BY
transaction date, since the encrypted field is no longer sortable. If you want to do a SUM()
against a set of encrypted expenditures, again you are out of luck.
Perhaps you could look at some ORMs and see if they have a row encryption feature, that might be a good starting point. I've not done this in PHP, but Mongoose ORM (for JavaScript) has a row encryption plugin. Maybe there are tutorials around that?
There was an approach/movement called translucent databases, and there was a book by the same name, but it did not really become popular. It was hoped that all sorts of highly private information was going to be hidden, hashed and fuzzed, but I don't think it really happened.
What exactly is the problem? Are you getting errors? If so, please provide them including what your expected vs actual results.
> I have also set up an xampp server to test on.
Did you also set up sendmail or equivalent?
http://php.net/manual/en/mail.requirements.php
> For the Mail functions to be available, PHP must have access to the sendmail binary on your system during compile time.
I can't say why "art" is doing this, that is quite odd. Strtotime is a very powerful function and it's quite possible this belongs to one of the algorithms. See http://php.net/manual/en/datetime.formats.relative.php, there are so many formats here and it doesn't even cover every possibility. I'm curious as to where "art" fits in though! I gave it a try and it worked, but changing the word slightly broke it.
<?php $url = 'http://www.pointstreak.com/baseball/standings.html?leagueid=193&amp;seasonid=30016';
// Get the contents of that URL. (the HTML) $page = file_get_contents($url);
//In case the page isn't in UTF-8. Converts it to UTF-8 $page = mb_convert_encoding($page, 'utf-8', mb_detect_encoding($page));
//Converts it all to HTML entities? (I think) $page = mb_convert_encoding($page, 'html-entities', 'utf-8');
//Creates a new DOM Document. (http://php.net/manual/en/class.domdocument.php) $dom = new DOMDocument();
//Seems like it is disabling the errors so if any errors happen nothing is stopped. libxml_use_internal_errors(true); $dom->loadHTML($page); libxml_use_internal_errors(false);
//Gets the element from the HTML $contentSection = $dom->getElementById('psbb_standings');
//Gets the content of that element $pageContent = $dom->saveHTML($contentSection);
echo $pageContent; ?>
I assume you're talking about the data from $forum_topic_reply_body?
You get an error because the apostrophe screws with your mysql insert. It's completely vulnerable to SQL injections because of this.
The newlines might be causing your problem.
http://php.net/manual/en/function.file.php
> Note: > > Each line in the resulting array will include the line ending, unless FILE_IGNORE_NEW_LINES is used, so you still need to use rtrim() if you do not want the line ending present.
I myself prefer to use built in functionality instead of doing system calls. Check out glob as a way to get matching files in a directory.
While you may be developing on an environment you control, using native php functionality is good for in case one day you are on someone else's environment, where they may have system calls disabled for security reasons.
You've got a couple minor problems.
First, Go can't find your packages, and running shell_exec("export GOPATH=/var/www/html/work")
doesn't work. If you can't set the GOPATH the right way, you need to change the ssh2_exec()
call to this.
$str = ssh2_exec( $this->connection, $cmd, null, ["GOPATH" => "/var/www/html/work"] );
Read the documentation for ssh2_exec. The fourth argument is an array of environment variables to set when running the command.
Second, Go is a compiled language, and you wouldn't even be running into this problem if you compiled your Go app first instead of using go run
. Which is really only meant to be used during development. You need to compile your Go app first with go build
, which gives you a binary file named package
. You take that binary, upload it to /home/www, and then change your command to this:
$command = "screen -d -m timeout -k 10 600 /home/www/package $pin $name $bots";
Third, why in the world did you name your Go package "package"? That's just confusing.
Fourth, your pastebin contains some.. um.. interesting choice of words which some people here might find offensive.
You have PHP, but you don't run a webserver. A webserver is something that processes http calls and instructs PHP, Ruby, or whatever to process things.
You can run an entire stack which is used in production (http://blog.frd.mn/install-nginx-php-fpm-mysql-and-phpmyadmin-on-os-x-mavericks-using-homebrew/) or run the built-in PHP development webserver (http://php.net/manual/en/features.commandline.webserver.php)
I personally have no experience with the later although I know it's the easiest one to start with.
That is one awesome link. Thanks.
Clearly...my answer is "yes", the ending notation in PHP is optional, even sometimes undesirable.
It's literally the first line of the documentation:
>Fetches a result row as an associative or numerically indexed array or both. By default, fetches as both.
$dt = DateTime::createFromFormat('z', 237); echo $dt->format('Y-m-d'); // 2015-08-26
Based on http://php.net/manual/en/function.date.php , z is the day of the year from 0-365. As /u/digitalend said, if you are doing something outside of the current year it could bring back some funky results.
Do you have sendmail (or equivalent) running on those machines?
http://php.net/manual/en/mail.requirements.php
> For the Mail functions to be available, PHP must have access to the sendmail binary on your system during compile time. If you use another mail program, such as qmail or postfix, be sure to use the appropriate sendmail wrappers that come with them.
You should definitly use the mysqli-class instead of the mysql_-functions for every database-connection.
Start to learn prepared-statements for mysqli because they are escaped by default and much safer.
Example:
$db = new mysqli(...);
$statement = $db->prepare("INSERT...(name
, id
) VALUES (?, ?);");
$statement->bind_param("si", $string_name", $id);
$statement->execute();
$res = $statement->get_result();
Example from the doc page says you need to set the cursor ... http://php.net/manual/en/function.sqlsrv-num-rows.php
From the example :
$sql = "SELECT * FROM Table_1"; $params = array(); $options = array( "Scrollable" => SQLSRV_CURSOR_KEYSET ); $stmt = sqlsrv_query( $conn, $sql , $params, $options );
It preforms a query on the database, using the SQL statement passed as the first parameter, which uses sprintf() based placeholders for values, and which the remainder of the passed values should match up to those place holders.
So, once it has those, it pulls out the first parameter which is the sql statement, then loops through the remaining ones, it then does urldecode on them, then also quotes them for mysqli.
If the query runs well, it will return an array with the results, otherwise it will return an array with the error.
I don't understand. The 2 responses you got from SO already told you what PHP function you can use. They both pointed you to file_put_contents
.
http://php.net/manual/en/function.file-put-contents.php
Granted it's not the only way but it's usable as is. Here are PHP's other file io functionality.
I would recommend the usort function. You can define a custom function to sort the array. Maybe something like
function sortChampions($a, $b) { //Needs to return a positive number if a > b, 0 if a==b and a negative number if a < b return $a['stats']['totalSessionsPlayed'] - $b['stats']['totalSessionsPlayed']; }
And then call
usort($data['champions'], 'sortChampions');
Which should return that champions array sorted in order. I'm a little rusty on my PHP and might have made some mistakes. If you need some more help, I'll be back online in the morning.
Note that the escaping method given here is inadequate for SQL queries and can still leave your code vulnerable to SQL injection attacks. SQL special characters (including quotes) in the values will break out of the quotes, essentially causing the same problem.
The best way to escape SQL queries is to use prepared queries, as this then handles all the escaping for you. Failing that you need to use mysqli_real_escape_string to escape values before entering them into an SQL query.
I would also advise against escaping data using htmlspecialchars() as you enter it into the database. htmlspecialchars() is for escaping output to HTML, so should only be used when you actually output to html (ie. in your views, after you've pulled the data out of the database). Otherwise, if you need to output the text somewhere else (for example, a plain text email or javascript), you'll have to unescape it with htmlspecialchars_decode first.
You also have the issue that you are making a connection to the database using the mysqli_*
based functions, but then later on are trying to use mysql_*
based functions.
The quick fix, change your connection, that is one location, but DO NOT DO IT, instead take the time to learn and change all the other database interactions to properly use mysqli_*
based functions. (PDO would actually better to learn if you have time)
Go learn about using prepared statements, eliminates the need for the whole *_real_escape_string()
needs. See this page:
http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
It can be a bit much at first, but you will so much be in a better pace for it.
First off, do not run your queries inside a loop. Doing that row by row is ill advised. You can query for the range in your where clause then loop through the results.
WHERE inverter_number
>= 1
AND `inverter_number' <= 5
Second, PHP has built in JSON functions so there is ~~not~~ no need to manually string your JSON together.
real_escape_string is not a viable security fix. You should be using prepared statements by binding variables.
It can be done with mysqli native functions, but the preferred method is to use the PDO abstraction layer.
change your do/while statement to be:
while ($row = $stmt->fetch()) { $rows[] = $row; }
a do/while will always execute at least once before it checks the condition. a while/do must check a condition before it proceeds. In your do/while, $row is never defined on the first iteration which is why you get the notice.
Alternatively, you can skip the loop entirely and collect all rows using fetchAll() like this:
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
You can't bind a target for a LIKE statement in that way. It will escape the % signs and treat them as literal. Instead, write your query like this:
$sql = "SELECT * FROM PRODUCTS WHERE PRODUCT_NAME LIKE CONCAT('%', ?, '%')";
then change your bind to:
$stmt->bindValue(1, $live, PDO::PARAM_STR);
As a side note, it's better not to perform queries for values like this. %value% is not indexable and will perform a full table scan. LIKE queries are indexable when your prefix is known:
%value% - not indexable %value - not indexable value% - indexable
You should look into filter_var.
http://php.net/manual/en/function.filter-var.php
FILTER_VALIDATE_EMAIL is the one you want. It's much easier than sifting through a regex laden expression.
Compare your preg_match to this filter_var('[email protected]', FILTER_VALIDATE_EMAIL)
You see where you're setting the value of those text/number fields to 0? Instead set that to the relevant $_POST['qtyx'] for that field.
You'll probably want something like this:
<input type="number" name="qty1" value="<?= isset($_POST['qty1']) ? $_POST['qty1'] : 0 ?>">
So if there is a quantity selected it will use that, if not it will use 0.
The other problem you mention is because isset() returns true if the value is set, otherwise false. It's not giving you the actual number. When you try and perform addition on a boolean, PHP converts that to a 1 or 0.
So this:
$totalQty = $qty1 + $qty2 + $qty3 + $qty4 + $qty5;
Is actually just 1 + 1 + 1 + 1 + 1 if they are all set.
The reason you're getting 4 instead of 5 is because you've mistyped one of your input fields. The first input should be qty1 instead of qty3, so isset(qty1) is returning false so you're doing 0 + 1 + 1 + 1 + 1.
You could probably use the same thing we did for the input field.
Instead of:
$qty1 = isset($_POST['qty1']); $qty2 = isset($_POST['qty2']);
use:
$qty1 = isset($_POST['qty1']) ? $_POST['qty1'] : 0; $qty2 = isset($_POST['qty2']) ? $_POST['qty2'] : 0; etc.
Edit: And as you're setting these first, you could clean up your inputs and just make them:
<input type="number" name="qty1" value="<?= $qty1 ?>">
> which also exists and does the exact same thing
It exists, but it's not exactly the same. It differs in terms of precedence - the order in which operators are processed.
This is more of a pet peeve of mine, but I personally hate seeing HTML echoed as a string. PHP supports echoing HTML or any static string by closing the PHP tag and just typing it out, and you can use the alternative syntax for the while loop to make it look cleaner (http://php.net/manual/en/control-structures.alternative-syntax.php)
So instead you could go:
<?php $i = 8; ?> <?php while ($i < 20) : ?> <tr> <td><?php echo $i; ?>:00</td> <td><?php echo isMeeting($i); ?></td> <td></td> <td></td> <td></td> <td></td> <td></td> </tr> <?php $i++; ?> <?php endwhile; ?>
It just makes it a lot easier to read in my eyes especially as your editor is more likely to be able to highlight the syntax properly
Well, for starters, the $_POST and $_GET really have nothing to do with MySQL, except that you use them to get information that CAN be passed into MySQL if you want to.. For testing purposes, you won't really need these at all .. until you come to making user input a part of your game.
If I were you, I would look at the php.net references on the mysqli functions, that is all you should really need to do what you're after. And know what to actually do when you know the commands, for example:
If you look at the second example here it gives you how to pull data from the database and display it on the page:
<?php //conection: $link = mysqli_connect("myhost","myuser","mypassw","mybd") or die("Error " . mysqli_error($link));
//consultation:
$query = "SELECT name FROM mytable" or die("Error in the consult.." . mysqli_error($link));
//execute the query.
$result = $link->query($query);
//display information:
while($row = mysqli_fetch_array($result)) { echo $row["name"] . "<br>"; } ?>
If you google 'php mysql insert', or 'php mysql query' or whatever you're looking for, you'll usually get the php command + references as the first hit.
If you're sure you need $_POST and $_GET at the moment, let me know .. but also let me know what you think you need it for, because this is just for pushing form data between client and server.
> What is the difference between PDO::FETCH_INTO and PDO::FETCH_CLASS.
Per the docs, it looks like FETCH_CLASS creates a new object, and FETCH_INTO updates an existing object. <http://php.net/manual/en/pdostatement.fetch.php>
I'd like to explain why this is happening, but also offer an answer/workaround to what I believe is your question.
PHP will not honor LastName=Bond&LastName=Smith&LastName=Johnson
if you are using $_GET
. By design, it will only provide you with the last value, Johnson
. Instead, the language prefers using an array of values, such as LastName[]=Bond&LastName[]=Smith&LastName[]=Johnson
.
If you want to parse that URL without needing []
, you'll have to do it manually. See this StackOverflow answer for more on that.
Now, to answer your question...
When you run the following:
$params = http_build_query([ 'LastName' => ['Bond', 'Smith', 'Johnson'] ]);
the output will be LastName%5B0%5D=Bond&LastName%5B1%5D=Smith&LastName%5B2%5D=Johnson
. This is because PHP thinks you want the []
or [#]
. Removing it is relatively easy using regex!
Try something like this, which will search for and remove %5B
followed by any number followed by %5D
.
$params = http_build_query([ 'LastName' => ['Bond', 'Smith', 'Johnson'] ]);
$cleanedParams = preg_replace('/%5B(\d+?)%5D/', '', $params);
You would just append it to the url in your link:
mywebsite.com?category=myawesomecategory
Like you access POST data with $_POST, you access data passed through the query string with $_GET. So, $_GET['category'] will be set to 'myawesomecategory'.
http://php.net/manual/en/reserved.variables.get.php
There's also the Post/Redirect/Get pattern, it's not appropriate for use here because the query string makes more sense, but to solve the issue you're talking about in situations where you want to use POST, it's a good solution.
I can see two mistakes at a glance; I have assumed that the data.txt file is a CSV file.
fgetcsv
(http://php.net/manual/en/function.fgetcsv.php) to get an array of elements.foreach($headers as header) {
(Line 10) is missing the dollar sign for $header, it should be foreach($headers as $header) {
With the adjustments above, your code does work as intended: http://pastie.org/private/zdtmgbhbojicdyq2tpw
PS: the hidden error was Parse error: syntax error, unexpected ')', expecting :: (T_PAAMAYIM_NEKUDOTAYIM) in *******.php on line 11
, which was the missing dollar sign for our header foreach loop.
The .= operator will concatenate the values, whereas = will just keep assigning the new value to $newstring on each iteration of the for loop. The last value to get set in the loop is 'w', so that's why $newstring equals 'w'.
.= is basically just adding another letter onto the end of the previous value.
Take a look at string operators in the at: http://php.net/manual/en/language.operators.string.php for a better explanation.
Autoloading (use spl_autoload_register
). Also, maybe I'm misunderstanding you here, but namespaces have been in PHP since 5.3.
I'd also look into Composer (maybe further down the road), which makes handling dependencies and loading classes very easy, but then you have to organize your classes according to the spec in krues8dr's link.
And PHP provides functions for passwords as of PHP 5.5 with a backwards compatible library to 5.3.7+ available.
Well, you definitely need to adjust the way index.php and other pages work in regards to including your header/footer... you are outputting HTML code, then you include header.php, which contains an entire shell for a page, then you output more code in index.php, then you include footer.php, which again has a full shell of a page..
In your givekey.php file, as already mentioned, it is wide open for SQL injection and using a deprecated set of functions to access mysql, but also there is the issue that you are trying to insert values into the database BEFORE you verify that they correctly solved the capcha. You are only showing the output if they solved it right.
Then in the database, you are inserting the text of the key that the user enters into the form, but later in the code for getkey.php, you have it setting the header to say you are outputing an image, yet all you are outputting is that same text from the form, not an image. You need to create an image, see the manual for GD for a common extension for creating/modifying images with PHP.
just noticed also in givekey.php, for when you go to show people the key to use when coming back to your site, you are trying to display an image, giving it the SRC as $row['pic'] yet that variable is not defined anywhere...
OK, first off, don't use sleep(300) - this is not a good idea as you're basically going to hang the web request until sleep() finishes, or more likely the request times out.
Instead, consider storing the failure count with the user record, along with a timestamp that indicates when the last failure occurred. Then you can use logic like this:
if attempts is >= 3, and timestamp is >= the current time minus 5 minutes tell them they're failing too much and give them an approximate number of minutes as to when they can try again. Disallow any login attempts until this condition stops occuring.
if failed attempt, and timestamp < the current time minus 5 minutes, update timestamp to current time, set attempts to 1. if timestamp >= the current time minus 5 minutes, increment attempts by 1, update timestamp to current time.
It is also strongly recommended that your authentication system use password_hash() and password_verify() if it isn't already.
My guess would be that you are trying to insert a word into the database that has a single quote in it. Your error starts with an s, so I would bet that you tried to enter one such as dog's so when the query ran it was doing this:
INSERT INTO english (word, hash) VALUES ('dog's','efc6d9091ed95f03533a0cbc7591cf53')
As you can see, that single quote messes things up. This is why you should use prepared statements, or at the very least use mysqli_real_escape_string (do not just use addslashes)
(Prepared statements though is the best route, as you are using the query in a loop, done properly, mysql gets the query ready once, and then you tell it to execute with different values during the loop. The way you are doing it, mysql processes (and has to prepare) the query every time)
<?php /** * Flattens an array, or returns FALSE on fail. */ function array_flatten($array) { if (!is_array($array)) { return FALSE; } $result = array(); foreach ($array as $key => $value) { if (is_array($value)) { $result = array_merge($result, array_flatten($value)); } else { $result[$key] = $value; } } return $result; } ?>
Edit: This is the documentation for how to do all this. http://php.net/manual/en/function.array-values.php When in doubt look through the PHP documentation.
Here's a very interesting article that shows how to install and switch between different versions of PHP. It is very easy to do this using Homebrew. Hope it helps!
https://getgrav.org/blog/macos-sierra-apache-multiple-php-versions
Ok I'll just tell you it's against the terms of service of credit card companies to store CC info. The options you have are to use Paypal, Stripe or go through the process of establishing a merchant account and getting a payment gateway. It's a liability you nor your company wants to assume.
My advice would be to use an existing solution. That could be wordpress with an event plugin w/paypal or stripe support or other ecommerce platform with similiar support.
Since I got that out of the way, if you want or have to write it yourself, this tutorial covers the basics and you can add the additional fields.
http://tutorialzine.com/2013/08/simple-registration-system-php-mysql/
For the payment part, there should be two additional fields payment_status and payment_token . Payment status should be numeric with possible options like
1 - paid
2 - will-pay
3 - pending
3 is just in case there's a delay from whatever processor you use. The payment_token field would be where you store the return from the processor so you can match the member to the transaction to verify manually if necessary.
When it's time for the event, write an SQL query to show all attendees and their status.
To answer my own question... I started using Wireshark to monitor the data being sent back and forth the socket.
It turns out I was sending the data in hex, when it should have been in binary.
I have concluded that you cannot truly appreciate all that frameworks do for you until you have had to go back to "native."
I have landed on Symfony as my go to for my projects, but if I have something small that I want to bang out then I fall back to Silex, which also uses Symfony components.
If security is your primary concern then go Symfony. If you feel the need to have complete control then go Silex.
If you don't understand arrays, you should stop everything you're doing until you do. They're a fundamental type in php, and not really that complicated once you understand how they work.
What you describe isn't a multidimensional array. It's just a basic associative array, and is very easy to sort.
Sample code from the link:
<?php
# create mock array of 10 users with random scores (0 - 100) in the format of id => score $scores = array(); for($x = 0; $x < 10; $x++) { $scores[$x] = mt_rand(0, 100); }
# scores before sorting print_r($scores);
# sort by score in descending order arsort($scores);
# get top 5 $top5 = array_slice($scores, 0, 5, true);
# scores after sorting, top 5 only print_r($top5);
I don’t think any of those are great sources... can’t say I’ve used any of them.
My only source is the php manual, and Laracasts.
https://laracasts.com/skills/php
I believe you would benefit from the same book I learned PHP. Try to find a copy of PHP and MySql for Dynamic Web Sites by Larry Ullman. It’s on google books for 20 dollars. He will show you how to build some stuff.
> I have cloned a repo on GitHub
Why did you clone the repo and not install using composer as recommended?
https://laravel.com/docs/5.5/installation
https://laracasts.com/series/laravel-from-scratch-2017/episodes/1
> Can anyone suggest any good php class tutorials.
If by that you mean a simple OOP tutorial, you could check out this series on Laracasts - https://laracasts.com/series/object-oriented-bootcamp-in-php. Perhaps this as well - https://laracasts.com/series/solid-principles-in-php (but only after the 1st).
For the record I used to be a subscriber at Laracasts for a couple of years. From what I remember, the content is generally pretty good and very beginner-friendly. Jeffrey is an excellent teacher and can explain complex ideas in very simple terms.
The problem about newbies creating a login system is, you end up with a non secure system.
Perhaps you should look into using a good 3rd party system like Auth0. PHP SDK: https://github.com/auth0/auth0-PHP
But of course, you still need some PHP knowledge to correctly implement it.
My recommendation is to pay someone competent to help you do this, or use an existing service.
>if I have more than 10,000 text pages and I wanna create search engine to get search terms from user and search in many database tables ,What the best approach to returning efficient results in a short time?
I would go for a dedicated solution like ElasticSearch. They have a demo of all the ELK stack with more than one thousand million indexed documents. https://www.elastic.co/products/elasticsearch
​
>and if I have page has moderate traffic and consequently hundreds of SQL requests per minute, resulting in overloading the server constantly and "hanging" the entire site. What could be done to reduce the load and smooth the situation?
It depends on your architecture/infrastructure, hard to solve without knowing more. The 'default' solution is to escalate horizontally with a load balancer, both PHP and MySQL machines.
Uploads: when you upload a file, it goes to the /tmp directory usually. Once the PHP program finishes, it's deleted. If there's a horrible error and the program crashes, the file might stay in /tmp. To preserve any uploaded files, you have to use move_uploaded_file() - and with that provision a place for it to be moved (file permissions need to be set.)
Emails: use a mail queue system. This is a topic that needs to be researched, but, short version is that it'll take some coordination with the hosting server.
Question: why are you doing this with CSV files? Do you have to keep using CSV, or can you store this information into a database at upload time? (Doing that might make your life easier, since you're partly recreating a database function with your query code.)
A class name shouldn't sound like the name of a function for one, this may sound minor but this should change how you are approaching creating your classes. You have all these methods that query the database but you are shoving them into a class with a very specific goal, if you want to display all the carriers in a table, are you going to use the class populateDropDown for that?
Trying to teach OOP here would be rather difficult and time-consuming and ultimately pointless because there are other people who do it much better. I would highly recommend looking into a PHP framework like laravel and just looking at how their classes are structured. I haven't watched the whole series but this seems like a pretty good resource too: https://www.youtube.com/playlist?list=PLfdtiltiRHWF5Rhuk7k4UAU1_yLAZzhWc
You would need to look into regular expressions and use preg_match_all to extract the markup http://uk1.php.net/preg_match.
Pretty good tool for checking your regular expression pattern http://regex101.com/#PCRE
Try this:
$pattern = "/{{2}([a-zA-Z]*)}{2}/";
$subject = "Dear {{name}}
In response to your query, your {{order}} will cost {{cost}}";
preg_match_all($pattern, $subject, $matches);
echo "<pre>"; var_dump($matches); echo "</pre>";
Give this:
array (size=2) 0 => array (size=3) 0 => string '{{name}}' (length=8) 1 => string '{{order}}' (length=9) 2 => string '{{cost}}' (length=8) 1 => array (size=3) 0 => string 'name' (length=4) 1 => string 'order' (length=5) 2 => string 'cost' (length=4)
I ended up creating my own version of a WAMP server (it was a portable launcher/controller with Apache, PHP, MySQL, FTP etc all connected by said launcher) many years ago (before diving into Linux), but it was still in beta. Before that though I used these guys: http://www.wampserver.com/en/
It should work straight out of the box, localhost only. For making it work on any IP, just turn online mode on. You can also configure the php.ini file yourself if you wish. Make sure to uninstall any MySQL, PHP and Apache services (Windows daemons) before installing it though, in case it gets confused.
Another alternative would be to run LAMP in a VM on 1 of the machines and have it either NATed, through the host, or as an actual client on the network.
Next time you need help with something: post the snippet you're having trouble with on some website, like pastebin, codepad or JsFiddle.
You can do this several ways, but i've shown you two here *note that you'll need to set an Method attribute if you want to actually POST data to thanks.php
I recommend using the crypt() function with with blowfish as the hashing algorithm and a per-user salt generated by passing a cryptographically secure PRNG.
In effect the code on creation of a password would look something like (assuming the use of mcrypt):
$_POST['password'] = 'someSecurePassword'; // Would be set by request
$seedSize = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB); if($seedSize === false) { trigger_error('Unable to generate salt seed size.', E_USER_ERROR); }
$seed = mcrypt_create_iv($seedSize); if($seed === false) { trigger_error('Unable to generate salt seed.', E_USER_ERROR); }
$salt = '$2a$15$' . substr(sha1($seed), 0, 22); $hashed = crypt($password, $salt);
You stored the value of $hashed in your users table, from this point forwards to compare the provided pass to the stored, hashed password you do something like this:
$_POST['password'] = 'someSecurePassword'; // Set by POST request $row['hashed_pass'] = '$2a$15$791b24deb2960c2355ce4uIBj2i54V8/8qPMtmtnjJnZNdb8MiVfu'; // Retrieved from db
if($row['hashed_pass'] === crypt($_POST['password'], $row['hashed_pass'])) { // successful login } else { // Failed login }
You could run a script say once a minute, that asks the remote page for headers and checks the last modified timestamp against your local version's timestamp, copying the remote file if needed.
http://php.net/manual/en/function.get-headers.php
I think this would be the lowest overhead, but maybe someone knows a better way.
According to the documentation for PDO, the second option you mention seems to be the proper convention to use. I don't use PDO myself so I can't honestly speak as to whether the first code block would work or not. You can certainly try it but it would seem more logical to follow the conventions outlined in the docs in my personal opinion.
tl;dr docs say use this :
$st->bindParam(':username', $data['username']); $st->bindParam(':password', $data['password']);
Use sqlite if it's available on your target server. It's SQL without the database server - just a flat file.
If you just use a flat file you're going to run into issues with file locking (what happens if two people try and modify it at the same time?) that are already solved for you in sqlite. And even if you do get that solved, your code is going to be a lot less efficient at searching or any other operation than sqlite.
Hell, if you want to get really adventurous, use PDO with an sqlite database... Then if you ever watch to switch to a MySQL database or something a little more heavy-duty, you could potentially do so without having to rewrite all of your code.
Your query is failing for some reason. mysql_query() will return false if an error occurs, so what you need to do is check the result and call mysql_error() to get the error message with something like this:
<?php // ... $dbresult = mysql_query("SELECT * FROM newsboard order by row_id desc limit 4", $dbconn); if ($dbresult) { // do whatever you need to on success } else { echo 'Error running query: '.mysql_error($dbconn); }
The easiest solution I can think of is requiring authentication by your web server.
http://www.yolinux.com/TUTORIALS/LinuxTutorialApacheAddingLoginSiteProtection.html
A suggestion would be to us VS Code (it's free) instead of Notepad++. https://code.visualstudio.com/
Install the PHP tools noted in the main screen. Then when you are coding, you can check if you have errors in the terminal view
I think the Cashier::findBillable() method is supposed to be on your user model. Did you add cashier to your model?
Cashier::findBillable() is going to look for a user (in your models) with that stripe id and return the billable instance. So if you haven't saved that id you created as a billable user in your model, it won't be found.
If you are just messing around and haven't added Cashier, you should be able to just use Stripe\Customer::retrieve() to get the data back.
Check the docs here: https://stripe.com/docs/api/customers/retrieve?lang=php
> is it possible?
Yes
> because let's I want to print a receipt how ?
You could have a page that loads a receipt in full screen and then you would just print as you would anything else in a browser.
> is it possible generate PDF receipts ?
Yes, either by creating PDF files or by just "printing to PDF" in the print view I mentioned earlier.
Good luck in building your POS!
Edit: You should take a look at Magento or Opencart or one of the eCommerce CMS systems...I know at least Opencart has a POS plugin so you could do some market research and see what sort of features others provide.