Multiple Keys to an array in if/else search - php

My code is pretty basic. I'm using an array to generate a datasheet for a product based on it's SKU and a filepath.
My array looks like this:
$a=array(
"/images/ManualSheets/factSheetCLASSIC.pdf"=>"KE800/6",
"/images/ManualSheets/factSheetMICRO.pdf"=>"KE800/12",
"/images/ManualSheets/factSheetSMALL.pdf"=>"KE4000/12",
"/images/ManualSheets/factSheetMEDIUM.pdf"=>"KE8000/12",
);
Where the first Key is the filepath, and the second Key is the SKU (as generated by the system) I then use an if/else to generate a button - so if a product is not in the array it returns a blank value and doesn't have a button which leads to nowhere
$factsheetweblink_url = array_search($product_sku,$a);
if ($factsheetweblink_url==false) {
echo " ";
}
else {
echo "<div class='productpagestockistBTN'>
<img src='/images/FactSheet_btn.png' >
</div>";
}
?>
This code works fine. The catch comes when I have products with different SKUs but the same datasheet file, (same brand and make but a different model). Currently I can only get it to work by uploading multiple copies of the datasheets with different names, but it's becoming a big waste of space.
I have tried using an array as a key to hold multiple values to the one key..
"/images/ManualSheets/factSheetMEDIUM.pdf"=> array("KE8000/12","KE7000/12"),
but it doesn't seem to be working... I'm not quite sure if I need to refine my if statement to search within the sub arrays as well or..?
Any help would be appreciated, thanks in advance.

You should use arrays like this:
$products = array(
0 => array(
"pdf" => "/images/ManualSheets/factSheetCLASSIC.pdf",
"skus" => array("KE800/6","KE900/6")
),
1 => array(
"pdf" => "/images/ManualSheets/factSheetCLASSIC3.pdf",
"skus" => array("KE100/6","KE200/6"))
);
This is because array_search returns just first row whit that key.
Then just do your own search function like:
function findBySku($items, $sku) {
$pdf = ""; // return empty if not found.
foreach($items as $row) {
if (in_array($sku, $row['skus'])) {
$pdf = $row['pdf'];
break;
}
}
return $pdf;
}
and call that function:
$pdf = findBySku($products, "some sku");

Related

Calling many Variables stored in outside file

The code I had help with the last couple weeks works great. The problem is it's creating way more needed includes and external files than I first thought and getting to be a challenge to keep track of.
I was told to use MySQL. That would be fine if the data was going to be used over again. The data is only used long enough to build the pages, print to pdf and then it's no longer needed and the files are deleted.
I have three templates that are used to create all the needed pages. Only the data is different but never the same to allow it to be saved beyond it's use.
The problem I started having is when 30+ pages are loaded into a single browser window so it can get processed to pdf, this is calling a few hundred includes and some are being missed. When each page is called by itself it all loads fine.
The other thing I can think of is to try and get the variables belonging to each page in it's own single file and have the page access that file. When I call the file with include "file.php"; it just prints everything to the screen and not where they are needed. That way each file would have 10 - 15 variables in it for each page This would eliminate over 400 external files down to 1+ images for each page.
Is putting them all in one separate file and then called possible?
I hope I explained this correctly.
Thanks in advance.
// What I would like in one file.
$item1 = "Data for Item one";
$photo1 = "img src string to image for item 1";
etc...
$item12 = "Data for Item 12";
$photo12 = "img src string to image for item 12";
This would then call the items in the proper location of the page.
echo "$item1";
echo "photo1";
etc...
echo "$item12";
echo "photo12";
You can use a MySQL database to store information like that. (Settings, etc.)
But you can also use arrays for this which is probably more advisable.
Solution with arrays
An array gives you the possibility to easily store and manage data of a similar type.
You create a new array like this:
$settings = array();
To store a value in it, you have several options:
name it as an integer (0, 1, 2, 3 etc.)
name it as a string ('item1', 'path2' etc.)
$settings = array('path1', 'path2');
This just stored 0 => 'path1' and 1 => 'path1'
To get the value of a key in an array:
echo $settings[0]; //or $settings{0}, outputs 'path1'
echo $settings[1]; //outputs 'path2'
Or you store it as a string:
$settings = array('picture1' => 'path1', 'picture2' => 'path2');
echo $settings['picture1']; //outputs 'path1'
Also, multidimensional arrays are possible:
$settings = array(
'paths' => array(
'picture1' => 'path1',
'picture2' => 'path2'
),
'language' => 'english'
);
You get a value of a multidimensional array like this:
//for every dimension a new [], outputs 'path1'
echo $settings['paths']['picture1'];
Then you can just easily store all your settings and require_once 'settings.php';.
If you want to learn more about arrays, go to the php.net documentation.
Example:
/php/settings.php
$settings = array(
'items' => array(
'item1' => 'Data for Item1',
'item12' => 'Data for Item12',
),
'photos' => array(
'photo1' => 'img src string to image for item 1',
'photo12' => 'img src string to image for item 12',
),
);
index.php
<?php
require_once '/php/settings.php';
echo $settings['items']['item1']; //outputs 'Data for Item1'
//Or you can even use a foreach loop
foreach($settings['items'] as $key) {
echo $key;
echo '<br>';
}
That prints out:
Data for Item1
Data for Item12
Hope this helped.

Associative array's loaded from database and display as 'columns'

I am trying to create an overview of product properties, for an invoice system.
So far, most things are comming together using classes and PDO.
I have the following issue.
In my class, i've created a function that builds my products array.
It loads some information from the database, to build this array.
This array, i want to use to display all the products i have selected:
$prod1 - $prod1Name - $prod1Descr - $prod1Price
$prod2 - $prod2name - $prod2Descr - $prod2Price
etc.
I figured that the Associative array would help me creating columns.
Though the problem is, that i do not understand a bit how to create multiple lines and columns this way.
I was thinking of something like:
$prod[1]["name"] - $prod[1]["descr"] - etc
Then to use this in a foreach loop to create as many new lines as required.
The only thing i could come up with is on my index.php (as shown below), cause using an index (the [1] defenition) does not seem to work the way i think it should be implemented.
For my understanding, i assigend the var in my class as an array, then redefine an array when loading the database information.
Could anyone tell me how i could try to solve this issue?
I have the following class:
<?
class Invoice{
var $vendorID;
var $product = array();
function product_array(){
global $db;
$query = $db->conn->prepare('
SELECT ProductName, ProductDescription, ProductDuration, ProductPriceInclVat, ProductPriceExclVat, ProductVatType
FROM products WHERE VendorID = :VendorID
');
$array = array (
'VendorID' => $this->vendorID
);
$query->execute($array);
$result = $query->fetchall();
if (empty($result)){
echo"Could not find any products matching your criteria.";
die;
} else {
foreach($result as $row) {
$this->product = array("Name" => $row['ProductName'],
"Description" => $row['ProductDescription'],
"Duration" => $row['ProductDuration'],
"PriceExclVat" => $row['ProductPriceExclVat'],
"PriceInclVat" => $row['ProductPriceInclVat'],
"VatType" => $row['ProductVatType']
);
}
}
}
}
?>
and then i have the following code on my index.php:
<?
$invoice = new Invoice();
foreach ($invoice->product as $key => $value){
echo $key . "<br>";
echo $value . "$value";
echo "<br>";
}
?>
When you are assigning the result arrays to the product property you are overwriting the array every time. You need to append to the array instead, so something like:
$this->product = array();
foreach($result as $row) {
$this->product[] = array(...);
}
Alternatively, you could just assign the results of fetchAll to the product property if you don't need to rename the field keys (or you could alias them in the SQL).
$query = $db->conn->prepare('
SELECT ProductName as Name,
ProductDescription as Description,
ProductDuration as Duration,
ProductPriceInclVat as PriceInclVat,
ProductPriceExclVat as PriceExclVat,
ProductVatType as VatType
FROM products WHERE VendorID = :VendorID
');
$array = array (
'VendorID' => $this->vendorID
);
$query->execute($array);
$product = $query->fetchall(PDO::FETCH_ASSOC);
The $product is now in the format you require.
After this you can avoid foreach loop in class invoice.
Other thing i noticed that you have made function product_array() which is not called,
so in index.php you are getting empty array (defined in class Invoice).
So in Invoice class it should be
$product = product_array()
and product_array function should return the value.

Match specific words in a string and categorize them

I'm pretty new to PHP so bear with me here. I'm trying to iterate through the words in a string of text, look for specific words, categorize them, and then count the number of times each word category was hit. I was able to do the easy part but I'm having problems counting the number of times each category is matched. Here's the main function that accepts my string:
public function matchThemeTest($query){
$marriageNum = 0;
$criminalNum = 0;
$contactNum = 0;
$keywords = array(
'background'=> array('category'=>'criminal'),
'marriage' => array('category'=>'marriage'),
'criminal' => array('category'=>'criminal'),
'arrest' => array('category'=>'criminal'),
'divorce' => array('category'=>'marriage'),
'person' => array('category'=>'contact'),
'contact' => array('category'=>'contact')
);
foreach (preg_split("/\s/", $query) as $word)
{
if (isset($keywords[$word]))
{
echo $keywords[$word]['category'];
if ($keywords[$word]['category'] == 'marriage') {
$marriageNum++;
}
echo $marriageNum;
}
}
//return reset($matches);
}
I've got a php fiddle setup here: http://phpfiddle.org/main/code/i4g-mdu that I've been playing around with. In it's current form, I can get the words into categories but I'm not sure how to count how many times each category gets matched. I feel like I need an additional loop or something simple to count but I'm not exactly sure where. Any advice is greatly appreciated. Thanks in advance.
You may need another array of data, to store the counts. Use an array like this:
$counts = array(
'criminal' => 0,
'marriage' => 0,
'contact' => 0
);
Then when you iterate through your foreach loop, you can use the $keywords[$word]['category'] as the key in $counts and increment it:
if(isset($keywords[$word]) {
$counts[$keywords[$word]['category']]++;
}
Then you can return the $counts array so the caller can use it to find out what the counts of each theme were:
return $counts;

Database logging in Zend Framework 2: wrong "extra" column name

I want to save log entries to my MySQL database from Zend Framework 2. I am using Zend\Log\Logger with a Zend\Log\Writer\Db writer. By supplying the writer with an array, one can choose which columns to save what data to (e.g. timestamp into a "log_date" column) and which data to save. Here is what I am doing:
$logger = new Zend\Log\Logger();
$mapping = array(
'timestamp' => 'timestamp_column',
'priority' => 'priority_column',
'message' => 'message_column',
'extra' => 'extra_column'
);
$logger->addWriter(new Zend\Log\Writer\Db($dbAdapter, 'table_name', $mapping));
$logger->err('some message', array('some extra information'));
The problem I am facing is that the array of column names and their values contain an incorrect column name for the "extra" column. Based on the array above, it should be inserting the value "some extra information" into the "extra_column" column. The problem is that the Zend\Log\Writer\Db class is using the letter "e" as the name of the extra column. This comes from the first letter of "extra_column" in my array above. For some reason, it is taking the first letter of "extra_column" and using it as the column name instead of the entire value.
I took a look at the source code. The mapEventIntoColumn method is being used to get the column names and values as an array. I copied in the relevant part of the method below.
// Example:
// $event = array('extra' => array(0 => 'some extra information'));
// $columnMap = array('extra' => 'extra_column');
// Return: array('e' => 'some extra information')
// Expected (without looking at the code below): array('extra_column' => 'some extra information')
protected function mapEventIntoColumn(array $event, array $columnMap = null) {
$data = array();
foreach ($event as $name => $value) {
if (is_array($value)) {
foreach ($value as $key => $subvalue) {
if (isset($columnMap[$name][$key])) {
$data[$columnMap[$name][$key]] = $subvalue;
}
}
}
}
return $data;
}
The $event parameter is an array containing the same keys as my $mapping array in my first code snippet and the values for the log message. The $columnMap parameter is the $mapping array from my first code snippet (array values are column names).
What actually seems to happen is that because I am passing in extra information as an array (this is required), the inner foreach loop is executed. Here, $key is 0 (the index) so it is actually doing like this: $columnMap['extra'][0]. This gives the letter "e" (the first letter in "extra_column"), which is used as the column name, where it should be the entire column name instead.
I tried to supply my own key in the extra array when calling the log method, but the same happens. The official documentation shows no examples of usage of the extra parameter. I want to insert information that can help me debug errors into my table, so I would like to use it.
Is this a bug or am I missing something? It seems really strange to me! I hope I explained it well enough - it is quite tricky!
Since Daniel M has not yet posted his comment as an answer, I will refer you to his comment which solved the problem.

PHP: Session 2-Dimensional Array - Track Viewed Products

I'm trying to create an array to display the last 5 products a customer has viewed.
The array is a 2 dimensional array like below...
$RView= array(
array( ID => "1001", RefCode => "Ref_01", Name => "Name_01" ),
...
array( ID => "1005", RefCode => "Ref_05", Name => "Name_05" )
);
The array values are retrieved from the products recordset and is designed to function as follows when a customer visits a product page.
Page will check if a Session Array exists
If yes, an array variable is created from existing Session
If no, a new array is created.
Array will add the new product details.
Array will count if there are more than 5 existing products in the array.
If yes, it will remove the oldest.
If no, moves to next step.
A Session is created/updated from the revised Array.
My current effort is attached below...
Many thanks for any help.
<?php
session_start()
// Get or Create Array
IF (isset($_SESSION['sessRView'])) {
$RView = ($_SESSION['sessRView']); }
ELSE {
$RView = array(array());
}
// Append currently viewed Product to Array
array(array_unshift($RView, $row_rsPrd['PrdID'], $row_rsPrd['RefCode'], $row_rsPrd['Name']));
// Check if more than 5 products exist in Array, if so delete.
IF (sizeof($RView) > 5) {
array(array_pop($RView)); }
// Update Session for next page
$_SESSION['sessRView'] = $RView;
// Display Array
for ($row = 0; $row < 5; $row++)
{
echo "<ul>";
echo "<li><a href='?PrdID=".$RView[$row]["PrdID"]."'>".$RView[$row]["RefCode"]."</a> : ".$RView[$row]["Name"]."</li>";
echo "</ul>";
}
?>
It's more or less right - just 2 lines need to be changed.
There's no need for the extra array() around array_unshift and array_pop.
When you use array_unshift you're pushing an array of items (not the id/codes individually) - I think you mean array_unshift($RView, array($prodid,$name,...))
What if $RView doesn't have 5 elements? In that case you're accessing undefined array indices (which may or may not show an error). Change it to a foreach loop: e.g.
foreach ($Rview as $prod) echo $prod['Name']...
It should work after you make these changes. You might want to clean up the coding style a bit, though :)
EDIT: Oh, I see, when you're referencing the array in the for loop it doesn't know that the array has "ProdID" and "Name" indices. When you make an array you have to define the indexes using the => operator.
Add indexes to the array when you array_unshift:
array_unshift($RView, array("ProdID" => $row_rsProd["ProdID"], "Name"...))
If row_rsProd isn't too big, you can just tack the entire row_rsprod onto $RView.
so change array_unshift(...) to just $RView[] = $row_rsProd
This way the indexes are preserved.
Alternatively you can change the indicies in the for loop to match. Right now the array you unshift onto $RView is 0-based - $RView[0][0] is the product ID for the first product, etc.
So you can change the stuff in the foreach loop to
echo "<li>..." $prod[0] $prod[1] $prod[2]
Hope that helps!

Categories